Depois de enviar muito, minha chamada send () faz com que meu programa pare completamente. Como isso é possível?
Então, basicamente, eu estou criando um servidor MMO em C ++ que roda em Linux. Funciona bem no começo, mas depois de talvez 40 segundos com 50 clientes, ele pausa completamente. Quando eu depuro, acho que basicamente o último quadro antes de parar de responder é syscall (), no ponto em que desaparece no kernel. Uma vez que desaparece no kernel, nunca retorna um valor ... é completamente desconcertante.
Os 50 clientes estão enviando 23 bytes a cada 250 milissegundos. Esses 23 bytes são transmitidos para todos os outros 49 clientes. Esse processo começa a ficar lento e, finalmente, chega a uma parada completa, onde o kernel nunca retorna de um syscall para o comando send (). Quais são algumas das possíveis razões aqui? Isso realmente está me deixando louco!
Uma opção que encontrei é o algoritmo Nagles, que força atrasos. Eu tentei alternar, mas ainda acontece no entanto.
Edit: O programa está preso aqui. Especificamente, no envio, que por sua vez chama 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;
}
Além disso, este é o método que chama o 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();
}
E esclarecer as conexões é uma instância do unordered_map do impulso. Os dados que o programa utiliza também não são exclusivos. Ele foi transmitido com sucesso para outros descritores de arquivos, mas engasga com um, pelo menos aparentemente, aleatório.