serveur multithreading ne peut pas enregistrer le dernier descripteur de socket

J’ai un projet dans lequel nous utilisons des threads. Le problème est que, chaque fois qu’un client spécifique envoie un message, il enregistre uniquement le dernier LAST client_sock qui a été créé, de sorte que je ne peux pas enregistrer l’appel précédent car chaque message envoyé par un client me répond à la dernière client qui a été créé signifie que les clients précédents sont exécutés.

class ServerTcp { private: pthread_t threads[50]; 

C’est la fonction qui crée les threads, qui envoie à recieveAndSend:

 void ServerTcp:: acceptTheReaquest(){ struct sockaddr_in client_sin; unsigned int addr_len = sizeof(client_sin); int sockFd; while((sockFd = accept(this->sock, (struct sockaddr *) &client_sin, &addr_len)) >= 0){ struct arg_struct args; //has only 2 values, initialized in next lines args.client_sock = sockFd; args.server = this; cout << "created " << sockFd << endl; pthread_create(&threads[numOfThreads],NULL, &ServerTcp::recieveAndSend, &args); numOfThreads++; } } 

c’est la fonction receiveAndSend:

 static void* ServerTcp:: recieveAndSend(void * args){ arg_struct* arguments = static_cast(args); char buffer[4096]; while (true){ memset(&buffer, 0, sizeof(buffer)); int bytes = arguments->server->recieveFromClient(buffer, arguments->client_sock); if (bytes >0){ ssortingng message = arguments->server->reciveOutput(buffer); arguments->server->sendTO(message, arguments->client_sock); } } return (void*)NULL; } 

c’est la fonction sendTo:

 void ServerTcp:: sendTO(ssortingng answer, int client_sock){ cout << "sending to " << client_sock <sent_bytes = send(client_sock, buffer, sizeof(buffer), 0); } 

sortie:

 created 4 received from 4 created 5 received from 5 

cela signifie que j’ai créé un thread pour client_sock 4, et que j’attend de recevoir de client_sock 4, et même pour client_sock 5. maintenant je veux que le serveur imprime l’envoi à 4, reçu de 4 – parce que j’ai utilisé le client avec client_sock 4 est le premier créé et celui à partir duquel le message a été envoyé, mais il contient toujours client_sock 5 et la sortie est la suivante:

 sending to 5 received from 5 

au lieu de

 sending to 4 received from 4 

…..AIDEZ-MOI??

Le bogue de votre code est le suivant (j’ai supprimé les lignes de code non pertinentes et nettoyé l’indentation):

 while((sockFd = accept(this->sock, (struct sockaddr *) &client_sin, &addr_len)) >= 0) { struct arg_struct args; args.client_sock = sockFd; args.server = this; pthread_create(&threads[numOfThreads],NULL, &ServerTcp::recieveAndSend, &args); numOfThreads++; } 

Vous instanciez arg_struct dans la scope locale, sur la stack. Vous arg_struct ensuite un pointeur sur l’ arg_struct au nouveau thread.

Le problème est que, après le retour de pthread_create () dans le thread parent, la boucle se termine (eh bien, l’itération actuelle de la boucle se termine et elle recommence), et l’ arg_struct n’est plus valide.

Cependant, le thread enfant essaiera d’y accéder indépendamment, via le pointeur reçu de pthread_create (), ce qui entraînera un comportement indéfini.

Le comportement que vous avez observé est le résultat de ce comportement indéfini (le thread parent instanciera une nouvelle arg_struct dans la stack, dans le même emplacement de mémoire brute, pour le deuxième thread, mais le premier thread sera toujours au même endroit, quand il se réveille).

Ce que vous devez faire est de construire arg_struct sur le tas, en utilisant l’opérateur new . De cette façon, l’ arg_struct instancié continuera d’exister, pour le nouveau thread. Bien entendu, le nouveau thread est responsable de la delete la arg_struct , une fois celle-ci terminée, pour éviter toute fuite de mémoire.