Décalage client / serveur

Je programme une application de sockets client / serveur C / C ++. À ce stade, le client se connecte au serveur toutes les 50 ms et envoie un message.

Tout semble fonctionner, mais le stream de données n’est pas continu: du coup, le serveur ne reçoit plus rien, puis 5 messages à la fois … Et parfois tout fonctionne …

Quelqu’un a-t-il une idée de l’origine de ce comportement étrange?

Une partie du code:

Client:

while (true) { if (SDL_GetTicks()-time>=50) { socket = new socket(); socket->write("blah"); message.clear(); message = socket->read(); socket->close(); delete socket; time=SDL_GetTicks(); } } 

Serveur:

 while (true) { fd_set readfs; struct timeval timeout={0,0}; FD_ZERO(&readfs); FD_SET(sock, &readfs); select(sock + 1, &readfs, NULL, NULL, &timeout) if(FD_ISSET(sock, &readfs)) { SOCKADDR_IN csin; socklen_t crecsize = sizeof csin; SOCKET csock = accept(sock, (SOCKADDR *) &csin, &crecsize); sock_err = send(csock, buffer, 32, 0); closesocket(csock); } } 

Modifications: 1. j’ai essayé de faire

 int flag = 1; setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof flag); 

Dans le client et le serveur, mais le problème est toujours là.

2.Oui ces connexions / déconnexions sont très inutiles, mais quand j’essaie d’écrire

 socket = new socket(); while (true) { if (SDL_GetTicks()-time>=50) { socket->write("blah"); message.clear(); message = socket->read(); time=SDL_GetTicks(); } } 

Ensuite, le message n’est envoyé qu’une fois (ou reçu) …

Finalement:

J’avais oublié d’appliquer TCP_NODELAY au socket client côté serveur. Maintenant cela fonctionne parfaitement! Je mets les processus en threads pour que les sockets restnt ouverts. Merci à tous 🙂

C’est ce qu’on appelle ” délai de Nagle “. Cet algorithme attend sur la stack TCP que davantage de données arrivent avant d’envoyer quoi que ce soit au réseau jusqu’à l’expiration du délai d’attente. Vous devez donc modifier le délai Nagle ( http://fourier.su/index.php?topic=249.0 ) ou désactiver le délai Nagle ( http://www.unixguide.net/network/socketfaq/2.16.shtml ), alors les données seront envoyées par appel send .

Comme d’autres ont déjà répondu, les retards que vous voyez sont dus à l’ algorithme Nagle intégré à TCP, qui peut être désactivé en définissant l’option de socket TCP_NODELAY .

Je tiens à vous signaler le fait que vos communications de socket sont très inefficaces en raison de connexions et déconnexions constantes. Chaque fois que le client se connecte au serveur, la négociation à trois voies est établie et la déconnexion de la connexion nécessite la réalisation de quatre paquets. Fondamentalement, vous perdez la plupart des avantages du TCP, mais vous subissez tous ses inconvénients.

Il serait beaucoup plus efficace que chaque client maintienne une connexion persistante au serveur. select(2) , ou mieux, epoll(4) sous Linux ou kqueue(2) sous FreeBSD et Mac, sont des kqueue(2) très pratiques pour gérer les E / S sur plusieurs sockets.

Vous pouvez utiliser l’option de socket TCP_NODELAY pour forcer l’envoi immédiat des données.