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

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

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Чтение с сокета без QDataStream  (Прочитано 11881 раз)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #15 : Июнь 29, 2011, 14:50 »

но ведь может возникнуть ситуация когда сигнатура начала/конца может оборваться и прийти (или не прийти хотя маловероятно в случае TCP) в другом пакете. как тогда быть?
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #16 : Июнь 29, 2011, 14:58 »

ждать пока придет
Записан

ArchLinux x86_64 / Win10 64 bit
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #17 : Июнь 29, 2011, 15:20 »

вот кусок кода чтения клиента под QNX где все работает: (хотя без каких либо проверок пока)
Код:
void	*	thread_func(void * params)
{
net_client_t * client = (net_client_t *)params;

ssize_t      received;
ssize_t header_size = sizeof(scb_msg_t);
ssize_t waitsize;
uint32_t flag = MSG_PEEK;


while(1)    //endless loop
{
while(1)
{
flag = MSG_PEEK | MSG_WAITALL;
waitsize = header_size;
received = recv(client->socket_descriptor,client->read_buffer,waitsize,flag);
if(received > 0)
{
if(((scb_msg_t*)client->read_buffer)->size>client->read_buffer_size)
{
printf("%s:%d receive error: header->size[%d]>read_buffer_size[%d]!\n",
client->remote_host.c_str(),client->remote_port,
((scb_msg_t*)client->read_buffer)->size,client->read_buffer_size);
break;
}

flag = MSG_WAITALL;

if(((scb_msg_t*)client->read_buffer)->size==0)
{
printf("%s:%d receive error: header->size==0, ignoring\n",client->remote_host.c_str(),client->remote_port);
received = recv(client->socket_descriptor,client->read_buffer,header_size,flag);
continue;
}

waitsize = (ssize_t)((scb_msg_t*)client->read_buffer)->size;

received = recv(client->socket_descriptor,client->read_buffer,waitsize,flag);
if(received == waitsize)
{
if(client->on_data_received) client->on_data_received(client,client->read_buffer,received);
}
else break;
}
else break;
}

client_disconnect(client);
sleep(2);
client_connect(client);
}


    #if defined(__WINDOWS__)
    return  0;
    #else
    return NULL;
    #endif
}
В этом коде все пакеты приходят правильно и целиком...
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #18 : Июнь 29, 2011, 16:04 »

вот как лучше сделать?
я думаю, сначала пакета ставить сигнатуру, например 'PACKBGN',/0, потом uint16_t lenght, потом данные если есть, в конце 'PACKEND',/0.
может в будущем и CRC.
теперь я так понимаю, сначала делаю peek.
далее надо найти в памяти сигнатуру начала. потом получить размер оставшийся, и копировать в буфер данные с сокета пока не получу сигнатуру конца или размер принятых данных не будет равен размеру, который шел после сигнатуры начала.
так делать? а если сигнатура обрывается где то по середине?
тогда какого размера брать буфер чтения?
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #19 : Июнь 29, 2011, 16:30 »

QAbstractSocket::LowDelayOption - частично решил проблему, теперь все приходит нормально (хотя конечно проверку я введу, но когда приедет разработчик сервера).
теперь непонятная проблема - когда я шлю на сервер запрос, открыть файл, то в ответ должен прийти пакет данных (структура scb_msg_t без данных за ней). И вот клиент QNX ее получает, а в Qt сигнал readyRead() не получаю. В чем может быть загвостка?
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


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