У меня есть приложение, которое принимает, обрабатывает и передает UDP-пакеты.Длинные задержки при отправке пакетов UDP
Все работает нормально, если номера портов для приема и передачи различны.
Если номера портов одинаковы и IP-адреса различны, он обычно работает нормально ИСКЛЮЧАЕТ, когда IP-адрес находится в той же подсети, что и компьютер, на котором запущено приложение. В этом последнем случае для функции send_to требуется несколько секунд, а не несколько миллисекунд, как обычно.
Rx Port Tx IP Tx Port Result
5001 Same 5002 OK Delay ~ 0.001 secs
subnet
5001 Different 5001 OK Delay ~ 0.001 secs
subnet
5001 Same 5001 Fails Delay > 2 secs
subnet
Вот краткая программа, которая демонстрирует проблему.
#include <ctime>
#include <iostream>
#include <string>
#include <boost/array.hpp>
#include <boost/asio.hpp>
using boost::asio::ip::udp;
using std::cout;
using std::endl;
int test(const std::string& output_IP)
{
try
{
unsigned short prev_seq_no;
boost::asio::io_service io_service;
// build the input socket
/* This is connected to a UDP client that is running continuously
sending messages that include an incrementing sequence number
*/
const int input_port = 5001;
udp::socket input_socket(io_service, udp::endpoint(udp::v4(), input_port));
// build the output socket
const std::string output_Port = "5001";
udp::resolver resolver(io_service);
udp::resolver::query query(udp::v4(), output_IP, output_Port);
udp::endpoint output_endpoint = *resolver.resolve(query);
udp::socket output_socket(io_service);
output_socket.open(udp::v4());
// double output buffer size
boost::asio::socket_base::send_buffer_size option(8192 * 2);
output_socket.set_option(option);
cout << "TX to " << output_endpoint.address() << ":" << output_endpoint.port() << endl;
int count = 0;
for (;;)
{
// receive packet
unsigned short recv_buf[ 20000 ];
udp::endpoint remote_endpoint;
boost::system::error_code error;
int bytes_received = input_socket.receive_from(boost::asio::buffer(recv_buf,20000),
remote_endpoint, 0, error);
if (error && error != boost::asio::error::message_size)
throw boost::system::system_error(error);
// start timer
__int64 TimeStart;
QueryPerformanceCounter((LARGE_INTEGER *)&TimeStart);
// send onwards
boost::system::error_code ignored_error;
output_socket.send_to(
boost::asio::buffer(recv_buf,bytes_received),
output_endpoint, 0, ignored_error);
// stop time and display tx time
__int64 TimeEnd;
QueryPerformanceCounter((LARGE_INTEGER *)&TimeEnd);
__int64 f;
QueryPerformanceFrequency((LARGE_INTEGER *)&f);
cout << "Send time secs " << (double) (TimeEnd - TimeStart)/(double) f << endl;
// stop after loops
if(count++ > 10)
break;
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
int main()
{
test("193.168.1.200");
test("192.168.1.200");
return 0;
}
Выход из этой программы, при работе на машине с адресом 192.168.1.101
TX to 193.168.1.200:5001
Send time secs 0.0232749
Send time secs 0.00541566
Send time secs 0.00924535
Send time secs 0.00449014
Send time secs 0.00616714
Send time secs 0.0199299
Send time secs 0.00746081
Send time secs 0.000157972
Send time secs 0.000246775
Send time secs 0.00775578
Send time secs 0.00477618
Send time secs 0.0187321
TX to 192.168.1.200:5001
Send time secs 1.39485
Send time secs 3.00026
Send time secs 3.00104
Send time secs 0.00025927
Send time secs 3.00163
Send time secs 2.99895
Send time secs 6.64908e-005
Send time secs 2.99864
Send time secs 2.98798
Send time secs 3.00001
Send time secs 3.00124
Send time secs 9.86207e-005
Почему это происходит? Есть ли способ уменьшить задержку?
Примечания:
Построенная с использованием кода :: блоков, работающих под различными вкусами Windows,
пакетов являются 10000 байт длиной
Проблема уходит, если я подключить компьютер запуск приложения во вторую сеть. Например, WWLAN (сотовая сеть «ракета палочке»)
Насколько я могу судить, это ситуация, которую мы имеем:
Это работает (разные порты, так же LAN):
Это также работает (те же порты, различные LANS):
Это не работает (те же порты, так же LAN):
Это похоже на работу (одни и те же порты, так же LAN, двойной подключением Module2 хоста)
Мне действительно трудно поверить. Я бы предложил удалить все исправления, чтобы повысить и создать ту же функциональность, используя необработанные сокеты BSD. – SergeyA
В любом случае отправка может занять 3 секунды. И ни в коем случае не существует общей проблемы с отправкой пакетов UDP по локальной сети, где все слушатели привязаны к одному и тому же порту. – SergeyA
@ the_non_believers Это происходит для трех разных людей в разных местах. – ravenspoint