crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

3 страниц V  < 1 2 3 >  
Тема закрытаНачать новую тему
> [РЕШЕНО] чтение sizeof( int ) в QTcpSocket
alexei
  опции профиля:
сообщение 27.3.2010, 15:02
Сообщение #11


Студент
*

Группа: Новичок
Сообщений: 11
Регистрация: 26.3.2010
Пользователь №: 1570

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(ViGOur @ 27.3.2010, 14:19) *
Попробуй читать с помощью qint64 QIODevice::read ( char * data, qint64 maxSize ), тоесть у тебя получится что-то вроде:
qint64 nRet=CClientGui::tcpSocket.read( &n, sizeof(int));


1) Такой код не скомпилировался.
2) Я когда пишу с сервера - сделал преобразование числа посредством htonl, байты пришли в нужном порядке (в сетевом порядке - на стороне qt-клиента не должно быть преобразование на таком низком уровне ручками я полагаю), осталось их правильно обработать:
bufAll - содержит данные сокета (считанные посредством readAll() )
    buf = new char[sizeof(int)];
    strcpy( buf, bufAll.left( sizeof( int ) ).data() );
    fprintf( stdout, "input read: %s\n", buf );
    fprintf( stdout, "input read (hex): %s\n", bufAll.left( sizeof( int ) ).toHex().data() ); // здесь идет вывод - 0000001b ( = 27 )
    _size += sizeof( int );
    sscanf( buf, "%d", &size );
    fprintf( stdout, "to read: %d bytes\n", size ); // а здесь показывается что size = 2285116
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 27.3.2010, 15:54
Сообщение #12


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Посмоти какое в твоем случае будет значение nSize:
int nSize=0;
memcpy( &nSize, bufAll.left( sizeof( int )).data(), sizeof( int));
код написан так же от руки и может не скомпилится, поправь его, bufAll.left( sizeof( int )) должен возвращать char *
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
alexei
  опции профиля:
сообщение 27.3.2010, 16:26
Сообщение #13


Студент
*

Группа: Новичок
Сообщений: 11
Регистрация: 26.3.2010
Пользователь №: 1570

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(ViGOur @ 27.3.2010, 15:54) *
Посмоти какое в твоем случае будет значение nSize:
int nSize=0;
memcpy( &nSize, bufAll.left( sizeof( int )).data(), sizeof( int));
код написан так же от руки и может не скомпилится, поправь его, bufAll.left( sizeof( int )) должен возвращать char *


В этом случае: nSize = 452984832.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 27.3.2010, 16:29
Сообщение #14


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


А если попробовать toAcii или toLocal8bit?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
alexei
  опции профиля:
сообщение 27.3.2010, 17:03
Сообщение #15


Студент
*

Группа: Новичок
Сообщений: 11
Регистрация: 26.3.2010
Пользователь №: 1570

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(ViGOur @ 27.3.2010, 16:29) *
А если попробовать toAcii или toLocal8bit?


Не понял к чему применять и зачем? У меня уже есть вывод в 16-ричном виде:
fprintf( stdout, "input read (hex): %s\n", bufAll.left( sizeof( int ) ).toHex().data() ); // здесь идет вывод - 0000001b ( = 27 )


Вопрос как из этого буфера уже правильно считать число?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 27.3.2010, 17:22
Сообщение #16


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


alexei, проблема в следующем: особо вникать в чужую проблему нет ни времени ни желания.
Если б ты привел подробную информацию об отправке и о приёме, то быстрее было бы найдено решение.
Напиши например так:
Отправляю:
Формат | Длинна | Сообщение
естест. | число 27 | "hello"
HEX | 1B | тоже в HEX'е

Принимаю в HEX:
00 00 1B 44 A9 ...
Вот если так опишешь, то может и сам поймёшь проблему
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 27.3.2010, 18:18
Сообщение #17


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Если у тебя данные выглядят как 0000001b, то при memcpy в nSize должно записаться число 27. :)
Иначе используй метод read он аналогичен твоему на других клиентах...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
alexei
  опции профиля:
сообщение 27.3.2010, 18:36
Сообщение #18


Студент
*

Группа: Новичок
Сообщений: 11
Регистрация: 26.3.2010
Пользователь №: 1570

Спасибо сказали: 0 раз(а)




Репутация:   0  


вот код отправки:
int  writeToClient (int fd, int n, char *data ) {
    int  nbytes;
    long int hton_n = htonl( n );

    CLog::SLogDate( "commFunc", "%d", n );
    nbytes = write( fd, &hton_n, sizeof( int ) );
    CLog::SLogDate( "commFunc", "%ld", hton_n );
    if( nbytes < 0 ) {
        fprintf( stderr, "Write: error writing to %d(fd) %d(int)\n", fd, n );
        return -1;
    }
    if (nbytes > 0) {
        #ifdef _SENDTHREAD
        printf("percent out\n");
        #endif
    }

    nbytes = write( fd, data, sizeof( char ) * n );
    if( nbytes < 0 ) {
        fprintf( stderr, "Write: error writing to %d(fd) %s(data)\n", fd, data );
        return -2;
    }

    CLog::LogDate( "commFunc", data );
    return 0;
}


Что отправляется:
Sat Mar 27 17:57:12 2010 commFunc 27
Sat Mar 27 17:57:12 2010 commFunc 452984832
Sat Mar 27 17:57:12 2010 commFunc <answer><id>0</id></answer>

Т.е. размер данных 27 байт, это число мы представили в стандартном для передачи по сети виде (htonl) - 452984832. Следующим пакетом будем пересылать "<answer><id>0</id></answer>" - 27 байт. Итого уехало клиенту - 31.

Что происходит на стороне клиента:
    int bytes = CClientGui::tcpSocket.bytesAvailable();
    fprintf( stdout, "available %d bytes\n", (int)bytes );
    fprintf( stdout, "before read buf: %s\n", responseArr.data() );
    responseArr.append( CClientGui::tcpSocket.readAll() );

// вызываем функцию (здесь responseArr = bufAll)

    strcpy( buf, bufAll.left( sizeof( int ) ).data() );
    fprintf( stdout, "input read: %s\n", buf );
    fprintf( stdout, "input read (hex): %s\n", bufAll.left( sizeof( int ) ).toHex().data() );


Что приехало:
available 31 bytes
before read buf: //здесь пусто
input read: //здесь пусто
input read (hex): 00 00 00 1b 3c 61 6e 73 77 65 72 3e 3c 69 64 3e 30 3c 2f 69 64 3e 3c 2f 61 6e 73 77 65 72 3e

"3c 61 6e 73 77 65 72 3e 3c 69 64 3e 30 3c 2f 69 64 3e 3c 2f 61 6e 73 77 65 72 3e" = "<answer><id>0</id></answer>" (проверить можно здесь: hex to string)

осталось разобраться с 00 00 00 1b

делаем так:
memcpy( &nSize, bufAll.left( sizeof( int )).data(), sizeof( int ) );


действительно nSize = 452984832
Даже htonl не надо делать, пока все писал, вот и разобрался.

Отдельное спасибо Litkevich Yuriy (memcpy выручило).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 27.3.2010, 18:39
Сообщение #19


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Ну вот, а то уже начал думать, что я совсем плохой стал... :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
alexei
  опции профиля:
сообщение 27.3.2010, 19:10
Сообщение #20


Студент
*

Группа: Новичок
Сообщений: 11
Регистрация: 26.3.2010
Пользователь №: 1570

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(ViGOur @ 27.3.2010, 18:18) *
Если у тебя данные выглядят как 0000001b, то при memcpy в nSize должно записаться число 27. :)
Иначе используй метод read он аналогичен твоему на других клиентах...


у меня данные пришли такого рода 1b000000. Прочиталось 27 все отлично, но беспокоит один вопрос - ручками не придется делать htonl на других платформах (если сходу кто ответи буду благодарен, если нет, путем ждать - когда у кого то возникнут проблемы =) )?

Еще просьба к администраторам.
Поскольку я не являюсь автором этой темы (открывал, когда не был зарегистрирован), не могли бы Вы проставить в названии "[ЗАКРЫТО]" ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

3 страниц V  < 1 2 3 >
Тема закрытаНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 20.4.2024, 2:27