Сейчас я использую epoll с блокирующими розетками. Буфер заполнен кажется.
то в основном я делаю MMO-сервер на C ++, который работает на Linux. Сначала он работает нормально, но через 40 секунд с 50 клиентами он полностью остановится. Когда я отлаживаю его, я обнаруживаю, что в основном последний кадр включен до того, как он перестает отвечать, это syscall (), после чего он исчезает в ядре. Как только он исчезает в ядре, он даже не возвращает значение ... это совершенно сбивает с толку.
Каждый из 50 клиентов отправляет 23 байта каждые 250 миллисекунд. Эти 23 байта затем передаются всем остальным 49 клиентам. Этот процесс начинает замедляться, а затем в конечном итоге полностью останавливается, когда ядро никогда не возвращается из системного вызова для команды send (). Каковы некоторые возможные причины здесь? Это действительно сводит меня с ума!
Один вариант, который я нашел, - это алгоритм Nagles, который вызывает задержки. Я пытался переключить это, но это все еще случается однако.
Редактировать: программа застряла здесь. В частности, при отправке, которая в свою очередь вызывает syscall ()
bool EpollManager::s_send(int curFD, unsigned char buf[], int bufLen, int flag)
// Meant to counteract partial sends
{
int sendRetVal = 0;
int bytesSent = 0;
while(bytesSent != bufLen)
{
print_buffer(buf, bufLen);
sendRetVal = send(curFD, buf + bytesSent, bufLen - bytesSent, flag);
cout << sendRetVal << " ";
if(sendRetVal == -1)
{
perror("Sending failed");
return false;
}
else
bytesSent += sendRetVal;
}
return true;
}
Также это метод, который вызывает s_send.
void EpollManager::broadcast(unsigned char msg[], int bytesRead, int sender)
{
for(iMap = connections.begin(); iMap != connections.end(); iMap++)
{
if(sender != iMap->first)
{
if(s_send(iMap->first, msg, bytesRead, 0)) // MSG_NOSIGNAL
{
if(debug)
{
print_buffer(msg, bytesRead);
cout << "sent on file descriptor " << iMap->first << '\n';
}
}
}
}
if(connections.find(sender) != connections.end())
connections[sender]->reset_batch();
}
И для выяснения связей это пример unordered_map для boost. Данные, которые заполняет программа, также не являются уникальными. Он успешно транслировался на другие файловые дескрипторы, но подавлял, по крайней мере, случайный.