Russian Qt Forum
Ноябрь 23, 2024, 11:53 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Qt сервер vs Action Script 3 клиент на Socket-ах. Проблема с передачей сообщений  (Прочитано 4707 раз)
Dzeto
Гость
« : Ноябрь 27, 2013, 22:31 »

Доброго времени суток.
Соединяю Action Script 3 клиент с сервером, написанном на Qt через socket'ы. Соединение отлично устанавливается, но есть проблемы с передачей сообщения. Сервер принимает его, но не может "распознать" что пришло.

Код в AS3: Когда устанавливаем соединение, пробуем сразу отослать данные на сервер.
Код:
private function connectHandler(event:Event):void
{
MyGlobalDispatcher.dispatch(new MyEvent(MyEventConstants.SERVER_CONNECT));

var command:String = "11";
var pack:ByteArray = new ByteArray();
pack.writeUTFBytes(command);
pack.position = 0;
this.writeShort(pack.length);
this.writeBytes(pack);
}

Код приема сообщения на сервере Qt:
Код:
void server::slotReadClient()
{
  QTcpSocket* pClientSocket = (QTcpSocket*)sender();
  QDataStream in(pClientSocket);
  in.setVersion(QDataStream::Qt_4_8);
 
  //Просто, чтобы знать, сколько пришло байт выводим их количество на "экран".
  emit my_status_signal_server("Messange received. Bytes Available: " + QString::number(pClientSocket->bytesAvailable()), "magenta");
 
  forever
  {
    if (nextBlockSize == 0)
    {
      if (pClientSocket->bytesAvailable() < sizeof(quint16))
      {
        break;
      }
      in » nextBlockSize;
    }

    if (pClientSocket->bytesAvailable() < nextBlockSize)
    {
      break;
    }
    QString msg_type, freq;
    in » msg_type » freq;
    emit my_status_signal_server("Messange received: " + msg_type + " " + freq, "black");
    nextBlockSize = 0;
  }
}

Скрин того, что пришло на сервер (а должно быть "11"):



P.S. Клиент, написанный на Qt успешно принимает и отправляет сообщения на сервер.
Записан
Dzeto
Гость
« Ответ #1 : Ноябрь 28, 2013, 16:37 »

На сервер поступают байты в UTF-8 кодировке, как я понял. И надо их правильно считать из сокета. Как это можно сделать, если я прав?
Записан
Dzeto
Гость
« Ответ #2 : Ноябрь 28, 2013, 21:54 »

Up
Записан
kibsoft
Хакер
*****
Offline Offline

Сообщений: 625


Просмотр профиля WWW
« Ответ #3 : Ноябрь 28, 2013, 23:02 »

Цитировать
QString msg_type, freq;
    in » msg_type » freq;
Как я понял, с сервера приходят строка и short int. Почему ты пытаешься 2 строки прочитать?
2) Судя по тому, что пришло 4 байта, значит строка у тебя не null terminated, а QDataStream читает массив чаров с \0 на конце через operator>>
3) QDataStream с QString через operator>> не работает, насколько я знаю.

Вывод: придумай свой протокол и читай данные через readRawData().
Или вообще не страдай фигней с придумыванием своего протокола, а просто юзай JSON RPC.
Записан

http://kibsoft.ru - Download the Qt Media Encoding Library here

The apps that were written using QtMEL:
http://srecorder.com - Screen recording software
Dzeto
Гость
« Ответ #4 : Ноябрь 28, 2013, 23:39 »

Цитировать
QString msg_type, freq;
    in » msg_type » freq;
Как я понял, с сервера приходят строка и short int. Почему ты пытаешься 2 строки прочитать?
2) Судя по тому, что пришло 4 байта, значит строка у тебя не null terminated, а QDataStream читает массив чаров с \0 на конце через operator>>
3) QDataStream с QString через operator>> не работает, насколько я знаю.

Вывод: придумай свой протокол и читай данные через readRawData().
Или вообще не страдай фигней с придумыванием своего протокола, а просто юзай JSON RPC.

Если я с Qt клиента(не путать с AS3 клиентом, который мне нужен) отправляю данные так:
Код:
void MyClient::slotSendToServer()
{
int row=ui.tableWidget->rowCount();
QString msg_type = "Test Message";

QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_8);

out<<quint16(0)<<msg_type<<ui.Edit_freq->text();
out.device()->seek(0);
out<<quint16(block.size() - sizeof(quint16));

tcpSocket->write(block);
}
то все данные успешно принимаются.
При этом на сервере могу прописать даже:
Код:
QString str1, str2, str3, str4
in » str1 » str2 » str3 » str4;
Данные придут и запишутся в str1 и str2, а  str3 и str4 без каких-либо проблем останутся пустыми. Следовательно QDataStream работает с QString через оператор >>.

Если с AS3 клиента(!) отправить строку "12", а на сервере считывать так:
Код:
quint8 command, command1; 
in » command » command1;
то в command будет записано 49, а в command1 - 50. Что соответствует ASCII кодам единицы и двойки.

По пункту 2 - можете пояснить что да как? Ваша мысль кажется очень здравой. В каком виде нужно передавать или читать строку, чтобы можно было ее вывести на экран?
Хотелось бы сколько-нибудь рабочий пример (и меньше ссылок:))

P.S. Про JSON RPS заинтересовало и даже очень, но давай сперва попробуем сделать без него.
« Последнее редактирование: Ноябрь 28, 2013, 23:46 от Dzeto » Записан
kibsoft
Хакер
*****
Offline Offline

Сообщений: 625


Просмотр профиля WWW
« Ответ #5 : Ноябрь 29, 2013, 01:13 »

Код:
out<<quint16(0)<<msg_type<<ui.Edit_freq->text();
Тут строки в поток пишутся так: "текст\0"
Таким образом, на сервере QDataStream первую строку читает до \0 и следующую также.

Цитировать
сли с AS3 клиента(!) отправить строку "12", а на сервере считывать так:
Пишете строку, а читаете quin32..Они по-разному кодируются.

Если у вас передаются исключительно строки, то вместо QDataStream можно использовать QTextStream на сервере.
Туда можно задать текстовый кодек:
Код:
stream.setCodec(QTextCodec::codecForName("UTF-8"))

Через QDataStream не получится сразу в UTF-8 читать.
Записан

http://kibsoft.ru - Download the Qt Media Encoding Library here

The apps that were written using QtMEL:
http://srecorder.com - Screen recording software
Dzeto
Гость
« Ответ #6 : Ноябрь 29, 2013, 01:39 »

Код:
out<<quint16(0)<<msg_type<<ui.Edit_freq->text();
Тут строки в поток пишутся так: "текст\0"
Таким образом, на сервере QDataStream первую строку читает до \0 и следующую также.

Цитировать
сли с AS3 клиента(!) отправить строку "12", а на сервере считывать так:
Пишете строку, а читаете quin32..Они по-разному кодируются.

Если у вас передаются исключительно строки, то вместо QDataStream можно использовать QTextStream на сервере.
Туда можно задать текстовый кодек:
Код:
stream.setCodec(QTextCodec::codecForName("UTF-8"))

Через QDataStream не получится сразу в UTF-8 читать.

Большое спасибо! Получилось сделать с помощью QTextStream и stream.setCodec(QTextCodec::codecForName("UTF-8")).
Данные не только строковые, но для начала подойдет.
« Последнее редактирование: Ноябрь 29, 2013, 01:41 от Dzeto » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.222 секунд. Запросов: 23.