Russian Qt Forum

Qt => Работа с сетью => Тема начата: Mark_T от Март 17, 2011, 11:31



Название: Tcp клиент, отправка сообщений по одному байту
Отправлено: Mark_T от Март 17, 2011, 11:31
Доброго всем времени суток!!! Проблема такая, создаю сокет QTcpSocket и и в цикле пытаюсь отправить несколько пакетов в которые записываю по одному байту.
На упрощенном примере пытаюсь так:
В конструкторе объявляю сокет:
Код:
m_pTcpSocket = new QTcpSocket(this);
Далее после коннекта

Код:
for (int i=0;i<4;i++) {

m_pTcpSocket->write("1");
}


Пытался и так ))) :

Код:

 
void SendToServer()

{

QByteArray arrBlock;

QDataStream out(&arrBlock, QIODevice::WriteOnly);

out.setVersion(QDataStream::Qt_4_0);

out.device()->seek(0);

QByteArray comArray=cmdInput->text().toAscii();



for (int i=0;i<comArray.length();i++) {

out<<(quint8)comArray[i];

m_pTcpSocket->write(arrBlock);
        out.device()->seek(0);

}

}


Проблема в том, что в обоих случаях генерируются не несколько пакетов (например,4 в упрощенном первом примере), как хотелось бы, по одному байту в каждом,а набор байтов. А так по сути задача разбить посимвольно строку и передать побайтно в разных пакетах. Заранее спасибо


Название: Re: Tcp клиент, отправка сообщений по одному байту
Отправлено: ufna от Март 17, 2011, 16:42
Дело в том, что есть две штуки, которые этим занимаются

1. после write нужно сделать flush() или что-то такое, выпала функция из головы
2. пакеты буферизирует система, чаще всего в 250-300мс


Название: Re: Tcp клиент, отправка сообщений по одному байту
Отправлено: BRE от Март 17, 2011, 17:56
http://traditio.ru/wiki/Алгоритм_Нагла (http://traditio.ru/wiki/Алгоритм_Нагла)


Название: Re: Tcp клиент, отправка сообщений по одному байту
Отправлено: Mark_T от Март 18, 2011, 08:52
Делаю flush()  - первый пакет отсылает один байт (в упрощенном примере), оставшиеся три байта буферизуются во второй пакет. Делаю :
Код:
m_pTcpSocket ->setSocketOption(QAbstractSocket::LowDelayOption,1);
ситуация такая же, даже после вставки задержки. Нормально работает действительно при задержке больше 250 мс. Но это для меня слишком медленно.


Название: Re: Tcp клиент, отправка сообщений по одному байту
Отправлено: Mark_T от Март 18, 2011, 08:58
Задача решилась установкой этой опции для каждого пакета. Если есть более изящный способ буду благодарен. Всем спасибо за советы!


Название: Re: Tcp клиент, отправка сообщений по одному байту
Отправлено: Akon от Март 18, 2011, 11:10
Буферизация возможна и на уровне QAbstractSocket (flush() по этой теме) и на системном уровне. Для снятия системной буферизации нужно установить размер системного буфера под передачу равным 0. В этом случае невозможно будет поместить в системный сокет новую порцию данных до тех пор, пока предыдущая не будет передана (с подтверждением). Для установки используются ioctl-команды (setsockopt()). Qt по ходу (я бегло просмотрел) не экспозирует все опции - QAbstractSocket::SocketOption содержит только два элемента, так что нужно использовать socketDescriptor() и лезть к системному API.