Я отправляю сообщения UDP размером 4 байта каждые 20 мс на сервер. Клиент и сервер находятся на одной машине.
Я испытываю латентность при получении такого огромного количества сообщений. После остановки и выхода из клиента сервер продолжает получать сообщения. Я полагаю, что должен быть встроен внутренний буфер сокета.
Сервер выполнен в C++. На стороне сервера я использую и массив из 10 буферов, каждый 64 байта, и я жду, чтобы получить каждое сообщение UDP здесь
static const int BUFFER_SIZE = 64;
static const int BUFFER_QUEUE_COUNT = 10;
int num = recvfrom(sSocket, buffer[bufferSelector], BUFFER_SIZE, 0, (SOCKADDR *)&senderAddr, &senderAddrSize);
Мне нужно как-то прекратить получать сообщения после закрытия клиента. Если сервер перезагружен, сообщения все еще поступают до тех пор, пока не будет пуст какой-либо внутренний буфер.
Теперь у меня есть два вопроса?
1. Как изменить размер внутреннего буфера? или
2. Как мне изменить архитектуру моего сервера, чтобы увеличить скорость получения?
Моя нынешняя архитектура основана на следующем коде:
while(true)
{
if(server->State == Stopping) break;
bool result = server->StartReceiving(*msg[msgIndex]);
if( result == true && server->State != Stopping)
{
server->numErrosCounter = 0;
msg[msgIndex]->Tag = (void *)server;
_beginthread(ActionThread, (unsigned int)0, msg[msgIndex]);
}
else if( result == false){
}
...
}
bool UDPCommunicator::StartReceiving(Message &msg)
{
State = Listening;
PrintStateLn();
sockaddr_in senderAddr;
int senderAddrSize = sizeof(senderAddr);
//int num = recvfrom(sSocket, buffer[bufferSelector], BUFFER_SIZE, NULL, NULL, NULL); // this works !!!
int num = recvfrom(sSocket, buffer[bufferSelector], BUFFER_SIZE, 0, (SOCKADDR *)&senderAddr, &senderAddrSize);
...
}
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ
Если клиент отправляет каждое сообщение с задержкой менее 40 мс, например 35, 30, 25, 20, возникает проблема медленной реакции. На скорости 40 мс там все нормально. Таким образом, 40 мс означает 25 кадров в секунду, 20 мс - 50 кадров в секунду.
Чтобы изменить размер буфера сокета, вы должны использовать функцию setsockopt()
и изменить параметр SO_RCVBUF
и/или SO_SNDBUF
.