Bonjour a tous !
Dans un projet je dois pouvoir avec un serveur en c qui utilise le TCP communiqué avec 2 clients, je me suis donc mis a vouloir utiliser les thread grâce a la librairie windows.h (je ne peut utiliser d'autres). Sauf que la je suis un peu perdu le programme ne fait pas trop ce que je voulais ,j'ai mon thread 1 qui se crée puis mon thread 2 qui se crée mais se ferme aussitôt ,puis après j'ai mon thread 1 qui tourne en boucle sans raison..... Pourquoi? Je pense qu'il doit y avoir un problème de synchronisation (mais je peux me tromper).
A noté que le client fonctionne parfaitement (si vous voulez je peut le mettre),le client dois pouvoir envoyer des informations au serveur.
Mon IDE est Code::Block et l'OS utilisé est sous Windows
Je précise que je suis débutant avec les thread, j'ai peut-être mal compris comment faire ?
Voici le code du server
// ********************************************************
// Les includes
// ********************************************************
#include <winsock2.h> // pour les fonctions socket
#include <stdio.h> // Pour les Sprintf
#include <windows.h>
int nMaxClients=3;//Nombre max de client accepter
int nClient=0;
//HANDLE Thread1,Thread2;
DWORD Thread1ID,Thread1Param;
DWORD Thread2ID,Thread2Param;
WSADATA initialisation_win32;
//ThreadClient
SOCKET id_de_la_socket; // Identifiant de la socket
// Identifiant de la nouvelle socknClientet
SOCKADDR_IN information_sur_la_source;
int i;
DWORD WINAPI ThreadClient(LPVOID lpParam)
{
// ********************************************************
// Reception des données
// ********************************************************
// SOCKET id_de_la_nouvelle_socket[nClient];
// id_de_la_nouvelle_socket[nClient] = (SOCKET)lpParam;
SOCKET id_de_la_nouvelle_socket;
id_de_la_nouvelle_socket = (SOCKET)lpParam;
char buffer[50];
int nombre_de_caractere=0;
printf("je suis le thread1 ");
printf("\nune personne se connecte : %s avec le port %d",inet_ntoa(information_sur_la_source.sin_addr),htons(information_sur_la_source.sin_port));
//nClient++;
//while (nombre_de_caractere !=SOCKET_ERROR )
printf("\nWAGETLASTERROR debut : %d",WSAGetLastError());
do
{
printf("je suis le thread 1\n ");
nombre_de_caractere=recv(id_de_la_nouvelle_socket,buffer,sizeof(buffer),0);
// Sleep(10);
if (nombre_de_caractere>0)
{
printf("\nVoici les donnees : %s nombre de caractère %d socket %d",buffer,nombre_de_caractere,lpParam);
}
else if (nombre_de_caractere==0)
{
printf("\nConnection perdue");
closesocket(id_de_la_nouvelle_socket);
}
else
{
printf("\nWAGETLASTERROR : %d",WSAGetLastError());
}
// Sleep(1000);ThreadClient
strcpy(buffer,"");
}
while(nombre_de_caractere >0);
printf("\nfin thread");
closesocket(id_de_la_nouvelle_socket);
//id_de_la_nouvelle_socket[0] = INVALID_SOCKET;
TerminateThread(ThreadClient, -1);
//nClient=nClient-1;
return 0;
}
DWORD WINAPI ThreadClient2(LPVOID lpParam)
{
// ********************************************************
// Reception des données
// ********************************************************
// SOCKET id_de_la_nouvelle_socket[nClient];
// id_de_la_nouvelle_socket[nClient] = (SOCKET)lpParam;
SOCKET id_de_la_nouvelle_socket;
id_de_la_nouvelle_socket = (SOCKET)lpParam;
char buffer[50];
int nombre_de_caractere=0;
printf("je suis le thread2" );
printf("\nune personne se connecte : %s avec le port %d",inet_ntoa(information_sur_la_source.sin_addr),htons(information_sur_la_source.sin_port));
//nClient++;
//while (nombre_de_caractere !=SOCKET_ERROR )
printf("\nWAGETLASTERROR debut : %d",WSAGetLastError());
do
{
printf("je suis le thread2 \n" );
nombre_de_caractere=recv(id_de_la_nouvelle_socket,buffer,sizeof(buffer),0);
// Sleep(10);
if (nombre_de_caractere>0)
{
printf("\nVoici les donnees : %s nombre de caractère %d socket %d",buffer,nombre_de_caractere,lpParam);
}
else if (nombre_de_caractere==0)
{
printf("\nConnection perdue");
closesocket(id_de_la_nouvelle_socket);
}
else
{
printf("\nWAGETLASTERROR : %d",WSAGetLastError());
}
// Sleep(1000);ThreadClient
strcpy(buffer,"");
}
while(nombre_de_caractere >0);
printf("\nfin thread");
closesocket(id_de_la_nouvelle_socket);
TerminateThread(ThreadClient2, -1);
// nClient=nClient-1;
return 0;
}
int main()
{
// ********************************************************
// Définition des variables
// ********************************************************
WSADATA initialisation_win32; // Variable permettant de récupérer la structure d'information sur l'initialisation
int erreur; // Variable permettant de récupérer la valeur de retour des fonctions utilisées
int tempo; // Variable temporaire de type int
//int nombre_de_caractere; // Indique le nombre de caractères qui a été reçu ou envoyé
//char buffer[65535]; // Tampon contenant les données reçues ou envoyées
SOCKET id_de_la_nouvelle_socket[nMaxClients-1];
HANDLE tab[2];
// Déclaration de la structure des informations lié à l'écoute
DWORD thread;
DWORD thread2;
printf("\nBonjour, vous etes du cote serveur. \n");
// ********************************************************
// Initialisation de Winsockwww.frameip.com
// ********************************************************
erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
if (erreur!=0)
printf("\nDesole, je ne peux pas initialiser Winsock du a l'erreur : %d %d",erreur,WSAGetLastError());
else
printf("\nWSAStartup : OK");
printf("\nWAGETLASTERROR : %d",WSAGetLastError());
// ********************************************************
// Ouverture d'une Socket
// ********************************************************
id_de_la_socket=socket(AF_INET,SOCK_STREAM,0);
if (id_de_la_socket==INVALID_SOCKET)
printf("\nDesole, je ne peux pas creer la socket du a l'erreur : %d",WSAGetLastError());
else
printf("\nsocket : OK");
// ********************************************************
// Lie la socket à une ip et un port d'écoute
// ********************************************************
information_sur_la_source.sin_family=AF_INET;
information_sur_la_source.sin_addr.s_addr=INADDR_ANY; // Ecoute sur toutes les IP locales
information_sur_la_source.sin_port=htons(33333); // Ecoute sur le port 33333
erreur=bind(id_de_la_socket,(struct sockaddr*)&information_sur_la_source,sizeof(information_sur_la_source));
if (erreur!=0)
printf("\nDesole, je ne peux pas ecouter ce port : %d %d",erreur,WSAGetLastError());
else
printf("\nbind : OK");
// ********************************************************
// Attente d'ouverture de session
// ********************************************************
erreur=99; // Initiation de erreur pour être sur que l'on va rentrer dans la boucle
while(erreur!=0) // Boucle tant qu'une demande de session (SYN) tcp n'a pas été reçu
erreur=listen(id_de_la_socket,5);
printf("\nlisten : OK");
// ********************************************************
// Acceptation de la demande d'ouverture de session
// ********************************************************
while(1)
{
printf("%d \n",nClient);
if(nClient<nMaxClients-1)
{
printf("\nAttente de la reception de demande d'ouverture de session tcp (SYN)");
tempo=sizeof(information_sur_la_source); // Passe par une variable afin d'utiliser un pointeur
id_de_la_nouvelle_socket[nClient]=accept(id_de_la_socket,(struct sockaddr*)&information_sur_la_source,&tempo);//accept la connexion
printf("\naccept : OK");
printf("appel thread1\n");
tab[0]=CreateThread(NULL,0,ThreadClient,(LPVOID)id_de_la_nouvelle_socket[0],0,&thread);
printf("appel thread2\n");
tab[1]=CreateThread(NULL,0,ThreadClient2,(LPVOID)id_de_la_nouvelle_socket[1],0,&thread2);
// WaitForMultipleObjects(2, tab, TRUE, INFINITE);
printf("fin thread");
// nClient++;
}
else if(id_de_la_nouvelle_socket[nClient]==INVALID_SOCKET)
{
printf("\nDesole, je ne peux pas accepter la session TCP du a l'erreur : %d",WSAGetLastError());
}
}
// TerminateThread(Thread1,0);
closesocket(id_de_la_nouvelle_socket[nClient]); //clos la socket
WSACleanup();
return 0;
}
Je vous remercie d'avance pour les réponses que vous pourriez m'apporter
Cordialement