Russian Qt Forum

Qt => Работа с сетью => Тема начата: Susenin от Октябрь 05, 2014, 18:44



Название: Почему такая большая задержка Ack по QTcpSocket?
Отправлено: Susenin от Октябрь 05, 2014, 18:44
Добрый день.

Пишу программу для соединения с прибором по TCP. Программа на компьютере выступает сервером.
Я обнаружил, что задержка подтверждения Tcp пакета 125 - 250 миллисекунд, в зависимости от мощности компьютера сервера.

Создал тестовых клиента и сервера. Проекты прикладываю. Задержки подтверждения сохраняются.
Это нормально? Какое должно быть типовое время Ack, при работе в одной сети (через роутер)?

В сервере перенос сокета в отдельный поток не изменило ничего.

Я обратил внимание на время подтверждения пакета Тcp т.к. в приборе стоит uIP стек  https://ru.wikipedia.org/wiki/UIP_(micro_IP). Этот стек ждет Ack на пакет, и только после этого посылает следующий.

Qt 5.3.1, Windows 7

Клиент.
Код
C++ (Qt)
#include <iostream>
#include <QCoreApplication>
#include <QTcpSocket>
#include <QTimer>
#include <QHostAddress>
 
int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
 
   QTcpSocket * socket = new QTcpSocket;
 
   QObject::connect(socket, static_cast<void(QTcpSocket::*)(QAbstractSocket::SocketError)>(&QTcpSocket::error), [=]()
   {
       std::cout << socket->errorString().toStdString() << std::endl;
   });
 
   socket->connectToHost(QHostAddress("192.168.0.6"), 10000);
 
   QTimer * timer = new QTimer;
   timer->start(100);
 
   QObject::connect(timer, &QTimer::timeout, [=]()
   {
       QByteArray data = "Some data";
       if (socket->write(data) != -1)
       {
           std::cout << "data sent ok" << std::endl;
       }
   });
 
   return a.exec();
}
 

Сервер.
Код
C++ (Qt)
#include <iostream>
#include <QCoreApplication>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>
#include <QObject>
 
int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
 
   QTcpSocket * socket = nullptr;
 
   QTcpServer * server = new QTcpServer;
 
   QObject::connect(server, &QTcpServer::newConnection, [&]()
   {
       if (socket)
       {
           delete socket;
       }
       socket = server->nextPendingConnection();
 
       std::cout  << "Connection established." << std::endl;
 
       if (socket)
       {
           QObject::connect(socket, &QTcpSocket::disconnected, []()
           {
               std::cout << "Connection lost." << std::endl;
           });
 
           QObject::connect(socket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error), [&] (QAbstractSocket::SocketError)
           {
               std::cout << "Error " << socket->errorString().toStdString() << std::endl;
           });
       }
   });
 
   if (!server->listen(QHostAddress("192.168.0.6"), 10000))
   {
       std::cout << "Can't start server:";
       std::cout << server->errorString().toStdString() << std::endl;
       return 0;
   }
   std::cout << "Server started." << std::endl;
 
   //QThread * serverThread = new QThread;
   //server->moveToThread(serverThread);
   //serverThread->start(QThread::TimeCriticalPriority);
 
   return a.exec();
}
 


Название: Re: Почему такая большая задержка Ack по QTcpSocket?
Отправлено: Bepec от Октябрь 05, 2014, 18:51
А почему вы думаете что это в Qt?
Какая задержка при использовании платформозависимого кода?


Название: Re: Почему такая большая задержка Ack по QTcpSocket?
Отправлено: Susenin от Октябрь 05, 2014, 20:18
А почему вы думаете что это в Qt?
Какая задержка при использовании платформозависимого кода?
Я не знаю, что и думать, поэтому и спрашиваю о типовом времени подтверждении на пакет.
Не хотелось, но, видимо, придется сделать тест сокетов без Qt.



Название: Re: Почему такая большая задержка Ack по QTcpSocket?
Отправлено: Bepec от Октябрь 05, 2014, 20:35
Видимо придётся, ибо эта информация довольно специфична.

На мой взгляд задержка в пределах нормы. Обычно для максимального быстродействия контролем доставки пренебрегают :)
Быстрее запросить пакет, чем дожидаться доставки :)


Название: Re: Почему такая большая задержка Ack по QTcpSocket?
Отправлено: Susenin от Октябрь 06, 2014, 00:25
Видимо придётся, ибо эта информация довольно специфична.

На мой взгляд задержка в пределах нормы. Обычно для максимального быстродействия контролем доставки пренебрегают :)
Быстрее запросить пакет, чем дожидаться доставки :)

Сделал нативный сервер. Разницы с Qt-шным не заметил. У меня Core-i3 3220, ответ через 200 мс.
Код
C++ (Qt)
#include <iostream>
#include <winsock2.h>
 
int main()
{
   WSAData wsa;
   WORD Version = MAKEWORD(2, 1);
 
   WSAStartup(Version, &wsa);
 
   SOCKET Listen = socket(AF_INET, SOCK_STREAM, NULL);
   SOCKET Connect = socket(AF_INET, SOCK_STREAM, NULL);
 
   SOCKADDR_IN Server;
 
   Server.sin_addr.s_addr = inet_addr("192.168.0.15");
   Server.sin_family = AF_INET;
   Server.sin_port = htons(10000);
 
   bind(Listen, (SOCKADDR*)&Server, sizeof(Server));
 
   listen(Listen, 1);
 
   std::cout << "Listeninig..." << std::endl;
 
   int size = sizeof(Server);
 
   while(1)
   {
       if (Connect = accept(Listen, (SOCKADDR*)&Server, &size))
       {
           std::cout << "Connection was reached" << std::endl;
       }
   }
 
   WSACleanup();
   std::cin.get();
   return 0;
}
 


Название: Re: Почему такая большая задержка Ack по QTcpSocket?
Отправлено: Bepec от Октябрь 06, 2014, 01:16
Вывод - это нормальное поведение.


Название: Re: Почему такая большая задержка Ack по QTcpSocket?
Отправлено: vulko от Октябрь 06, 2014, 10:37
Работа TCP через рутер сильно зависит от загрузки этого рутера.
Но вообще 100-200мс это крайне много.

Время не должно разительно отличаться от времени ping'а того же сервера.

Судя по библиотеке код работает на микроконтроллере? Возможно это предел его возможностей просто. Либо код для микроконтроллера не оптимален.


Название: Re: Почему такая большая задержка Ack по QTcpSocket?
Отправлено: Bepec от Октябрь 06, 2014, 12:15
Не, тут скорее дело в другом. В том, что отправка флага доставки не является приоритетной задачей. Я ж писал уже - для повышения быстродействия стандартный контроль доставки выбрасывается к чертям. Быстрее пару раз запросить новые кадры, чем ждать подтверждения.


Название: Re: Почему такая большая задержка Ack по QTcpSocket?
Отправлено: IMPOMEZIA от Октябрь 07, 2014, 23:23
Код:
QAbstractSocket::LowDelayOption