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

Войти
 
  Начало Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
  Просмотр сообщений
Страниц: 1 ... 64 65 [66] 67 68 69
976  Qt / Работа с сетью / Re: Чтение с сокета без QDataStream : Июнь 29, 2011, 16:30
QAbstractSocket::LowDelayOption - частично решил проблему, теперь все приходит нормально (хотя конечно проверку я введу, но когда приедет разработчик сервера).
теперь непонятная проблема - когда я шлю на сервер запрос, открыть файл, то в ответ должен прийти пакет данных (структура scb_msg_t без данных за ней). И вот клиент QNX ее получает, а в Qt сигнал readyRead() не получаю. В чем может быть загвостка?
977  Qt / Работа с сетью / Re: Чтение с сокета без QDataStream : Июнь 29, 2011, 16:04
вот как лучше сделать?
я думаю, сначала пакета ставить сигнатуру, например 'PACKBGN',/0, потом uint16_t lenght, потом данные если есть, в конце 'PACKEND',/0.
может в будущем и CRC.
теперь я так понимаю, сначала делаю peek.
далее надо найти в памяти сигнатуру начала. потом получить размер оставшийся, и копировать в буфер данные с сокета пока не получу сигнатуру конца или размер принятых данных не будет равен размеру, который шел после сигнатуры начала.
так делать? а если сигнатура обрывается где то по середине?
тогда какого размера брать буфер чтения?
978  Qt / Работа с сетью / Re: Чтение с сокета без QDataStream : Июнь 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
}
В этом коде все пакеты приходят правильно и целиком...
979  Qt / Работа с сетью / Re: Чтение с сокета без QDataStream : Июнь 29, 2011, 14:50
но ведь может возникнуть ситуация когда сигнатура начала/конца может оборваться и прийти (или не прийти хотя маловероятно в случае TCP) в другом пакете. как тогда быть?
980  Qt / Работа с сетью / Re: Чтение с сокета без QDataStream : Июнь 29, 2011, 14:27
дело в том, что многие данные из p1-p8 используются, поэтому вырезать заголовок не имеет смысла
981  Qt / Работа с сетью / Re: Чтение с сокета без QDataStream : Июнь 29, 2011, 14:23
предложите ваш вариант?
сервер уже написан (писал не я) и работает.
т.е. в начало и конец заголовка положить сигнатуру?
потом в очередном peek её искать? если нашёл, тогда уже читать как выше изложено?
982  Qt / Работа с сетью / Re: Чтение с сокета без QDataStream : Июнь 29, 2011, 14:13
выравнивание мы привели к одинаковому значению.
например проблем на qnx клиенте не возникает, и все данные приходят как надо. но механизм приема там немного другой в силу специфики ОС.
983  Qt / Работа с сетью / Re: Чтение с сокета без QDataStream : Июнь 29, 2011, 13:59
Я так и не понял к чему то что по ссылке?
А наш протокол довольно протостой.
Есть заголовок в виде структуры, у которой несколько полей.
Код:
typedef struct
{
        uint32_t family; //Семейство
        uint32_t action; //Действие
        uint32_t size; //размер пакета
        time_t time;
        int32_t p1;
        int32_t p2;
        int32_t p3;
        int32_t p4;
        int32_t p5;
        int32_t p6;
        int32_t p7;
        int32_t p8;
}   scb_msg_t;// __attribute__ ((packed));
Как видно, в size заклдаывается длина пакета (заголовок + данные если есть за ним).
На клиенте мне нужно получить даголовок и данные если есть за ним.
984  Qt / Работа с сетью / Re: Чтение с сокета без QDataStream : Июнь 29, 2011, 12:25
интересно, что некоторые пакеты не приходят, по карайней мере я не получаю сигнал readyRead, когда например в другой программе(которая работает по этому же протоколу но написанной под QNX на socket API) все приходит. В чем может быть проблема?
В данном случае, я ожидаю пакет длиной 48 байт. Ощущение ,что пакеты меньше или равные 48 байтам мне не доходят.
985  Qt / Работа с сетью / Re: Чтение с сокета без QDataStream : Июнь 29, 2011, 11:56
Вот что у меня получилось.
Код:
void     QGenericArmClient::readyRead()
{
    if(fblockSize==0) //читаем заголовок пакета (остальное остается в буфере)
    {
        if(fsocket->bytesAvailable()<sizeof(scb_msg_t)) return; //если данных меньше чем заголовок - игнорируем
        freceived = fsocket->read(frawBuffer,sizeof(scb_msg_t)); //получаем заголовок
        if(fframeHeader->size==0) //если в заголовке стоит длина 0, игнорируем этот пакет
        {
            freceived = 0;
            return;
        }
    }

    int bytesAvail = fsocket->bytesAvailable(); //сколько еще в буфере данных?
    if(bytesAvail) //если что то есть
    {
        fblockSize = fsocket->read(&frawBuffer[freceived],bytesAvail); //читаем очередной блок данных со смещением на уже принятые
        freceived+=fblockSize; //обновляем колво принятых данных
    }

    if(freceived>=fframeHeader->size) //если данных достаточно
    {
        fmutex->lock();
        qMemCopy(fdestBuffer,frawBuffer,freceived); //копируем в результирующий буфер
        fmutex->unlock();
        emit    frameReceived(freceived); //даем сигнал о том что данные приняты
        freceived = 0; //обнуляем счетчик принятых данных
    }
}
Все работает, но такой вопрос, может ли быть такая ситуация, когда в следующем
Код:
 int bytesAvail = fsocket->bytesAvailable(); //сколько еще в буфере данных?
    if(bytesAvail) //если что то есть
    {
        fblockSize = fsocket->read(&frawBuffer[freceived],bytesAvail); //читаем очередной блок данных со смещением на уже принятые
        freceived+=fblockSize; //обновляем колво принятых данных
    }
может прийти часть следующего пакета?
986  Qt / Установка, сборка, отладка, тестирование / Qt под iOS существует? : Июнь 29, 2011, 10:19
Существует ли сборка Qt под iOS. Гугл не знает. Реально ли самому собрать и что для этого нужно?
987  Qt / Пользовательский интерфейс (GUI) / Re: Как узнать, какой пункт меню был выбран? : Июнь 24, 2011, 12:00
спасибо, буду пробовать!
988  Qt / Пользовательский интерфейс (GUI) / Re: Как узнать, какой пункт меню был выбран? : Июнь 23, 2011, 17:13
sender у кого брать?
989  Qt / Пользовательский интерфейс (GUI) / Как узнать, какой пункт меню был выбран? : Июнь 23, 2011, 14:30
Формируется главное меню окна динамически.
К примеру, есть несколько клиентов, для каждого клиента свой пункт меню.
Все пункты меню нужно привязать к одному слоту этого окна, в котором нужно произвести некоторые предварительные настройки программы, а затем обратиться к конкретному клиенту.
Как это сделать?
990  Qt / Пользовательский интерфейс (GUI) / Re: Удаление пунктов меню из menuBar главного окна : Июнь 22, 2011, 17:55
спасибо, работает!
Страниц: 1 ... 64 65 [66] 67 68 69

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