Hello,
Before the code following, I used blocking recv.
So, now I use non-blocking sockets with ioctlsocket before the loop.
Previously, my code works perfectly and connection was gracefully closed with shutdown function.
But since I use non-blocking sockets, when I call shutdown, it returns SOCKET_ERROR with WSA = 10035 = WSAEWOULDBLOCK
I don't know how to resolve my problem can you help me ?
This is my code :
Code:
CodeErreur = ioctlsocket(ParametresSocket->IDSocketClient, FIONBIO, &ModeNonBloquant); // On active le mode non bloquant sur la socket client
if (CodeErreur != 0)
{
sprintf(TexteErreur,"Impossible de passer la socket en mode non-bloquant du à l'erreur : %d",WSAGetLastError());
MessageBox(NULL,TexteErreur,"Erreur Générale !",MB_OK | MB_ICONERROR);
closesocket(ParametresSocket->IDSocketServeur);
return -1;
}
do
{
/* Reception des données */
LongueurMessage = recv(ParametresSocket->IDSocketClient, (char*)&InfosRecues, sizeof(StructEchangee),0); // On recoit la position
if ((LongueurMessage == SOCKET_ERROR) && (WSAGetLastError() != WSAEWOULDBLOCK)) // Si on a une erreur mais que ce n'est pas du au bloquage de la socket
{
sprintf(TexteErreur,"Impossible de recevoir les données du à l'erreur : %d",WSAGetLastError());
MessageBox(NULL,TexteErreur,"Erreur Générale !",MB_OK | MB_ICONERROR);
closesocket(ParametresSocket->IDSocketClient);
closesocket(ParametresSocket->IDSocketServeur);
return -1;
}
ParametresSocket->PositionJoueurDistant.x = InfosRecues.PositionJoueurLocal.x; // On met la position du joueur distant dans notre structure locale
ParametresSocket->PositionJoueurDistant.y = InfosRecues.PositionJoueurLocal.y;
if(LongueurMessage == 0) // Recv vaut 0 si on a recu un shutdown
{
ParametresSocket->ActiverTransmission = FALSE; // A notre tour on desactive la transmission ce qui va envoyer un shutdown en reponse
}
/* Envoi des données */
if(((ParametresSocket->PositionJoueurLocal.x != InfosTransmises.PositionJoueurLocal.x) || (ParametresSocket->PositionJoueurLocal.y != InfosTransmises.PositionJoueurLocal.y)) && (ParametresSocket->ActiverTransmission))
{ // Si notre position a changé et qu'on est pas en train de shutdown
InfosTransmises.PositionJoueurLocal.x = ParametresSocket->PositionJoueurLocal.x; // On remplace la position precedente par la position actuelle
InfosTransmises.PositionJoueurLocal.y = ParametresSocket->PositionJoueurLocal.y; // Ca evite d'envoyer des paquets alors qu'on ne bouge pas
LongueurMessage = send(ParametresSocket->IDSocketClient, (char*)&InfosTransmises, sizeof(StructEchangee),0);
if (LongueurMessage == SOCKET_ERROR)
{
sprintf(TexteErreur,"Impossible d'envoyer les données du à l'erreur : %d",WSAGetLastError());
MessageBox(NULL,TexteErreur,"Erreur Générale !",MB_OK | MB_ICONERROR);
closesocket(ParametresSocket->IDSocketClient);
closesocket(ParametresSocket->IDSocketServeur);
return -1;
}
}
/* Desactivation de la connexion */
if(!ParametresSocket->ActiverTransmission) // Si on doit arreter la transmission
{
CodeErreur = shutdown(ParametresSocket->IDSocketClient, 1); // On shutdown les operations sur la socket (envoie d'un bit FIN)
if (LongueurMessage == SOCKET_ERROR)
{
sprintf(TexteErreur,"serv:Impossible de shutdown la socket du a l'erreur : %d",WSAGetLastError());
MessageBox(NULL,TexteErreur,"Erreur Générale !",MB_OK | MB_ICONERROR);
closesocket(ParametresSocket->IDSocketClient);
closesocket(ParametresSocket->IDSocketServeur);
return -1;
}
}
sleep(30);
} while (LongueurMessage != 0); // Shutdown terminé dans les deux sens, on ferme proprement les sockets