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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Почему такая большая задержка Ack по QTcpSocket?  (Прочитано 5816 раз)
Susenin
Новичок

Offline Offline

Сообщений: 35


Просмотр профиля
« : Октябрь 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();
}
 
« Последнее редактирование: Октябрь 05, 2014, 18:50 от Susenin » Записан
Bepec
Гость
« Ответ #1 : Октябрь 05, 2014, 18:51 »

А почему вы думаете что это в Qt?
Какая задержка при использовании платформозависимого кода?
Записан
Susenin
Новичок

Offline Offline

Сообщений: 35


Просмотр профиля
« Ответ #2 : Октябрь 05, 2014, 20:18 »

А почему вы думаете что это в Qt?
Какая задержка при использовании платформозависимого кода?
Я не знаю, что и думать, поэтому и спрашиваю о типовом времени подтверждении на пакет.
Не хотелось, но, видимо, придется сделать тест сокетов без Qt.

Записан
Bepec
Гость
« Ответ #3 : Октябрь 05, 2014, 20:35 »

Видимо придётся, ибо эта информация довольно специфична.

На мой взгляд задержка в пределах нормы. Обычно для максимального быстродействия контролем доставки пренебрегают Улыбающийся
Быстрее запросить пакет, чем дожидаться доставки Улыбающийся
« Последнее редактирование: Октябрь 05, 2014, 20:48 от Bepec » Записан
Susenin
Новичок

Offline Offline

Сообщений: 35


Просмотр профиля
« Ответ #4 : Октябрь 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;
}
 
Записан
Bepec
Гость
« Ответ #5 : Октябрь 06, 2014, 01:16 »

Вывод - это нормальное поведение.
Записан
vulko
Гость
« Ответ #6 : Октябрь 06, 2014, 10:37 »

Работа TCP через рутер сильно зависит от загрузки этого рутера.
Но вообще 100-200мс это крайне много.

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

Судя по библиотеке код работает на микроконтроллере? Возможно это предел его возможностей просто. Либо код для микроконтроллера не оптимален.
Записан
Bepec
Гость
« Ответ #7 : Октябрь 06, 2014, 12:15 »

Не, тут скорее дело в другом. В том, что отправка флага доставки не является приоритетной задачей. Я ж писал уже - для повышения быстродействия стандартный контроль доставки выбрасывается к чертям. Быстрее пару раз запросить новые кадры, чем ждать подтверждения.
Записан
IMPOMEZIA
Гость
« Ответ #8 : Октябрь 07, 2014, 23:23 »

Код:
QAbstractSocket::LowDelayOption
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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