IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

POSIX C Discussion :

Programmation réseau : socket et thread


Sujet :

POSIX C

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Points : 7
    Points
    7
    Par défaut Programmation réseau : socket et thread
    Bonjour,

    je dois coder un système de ventes aux enchères en C pour le serveur et en java (interface graphique) pour le client
    donc en gros, dès qu'il y a un accept() au niveau du serveur, on lance un thread avec en paramètre le socket renvoyé par le accept()
    Pour l'instant ça fonctionne.
    Dans la méthode associée au thread, on récupère une action (avec un switch) que le client a envoyé(par exemple 1 correspond à une inscription, 2 à une identification, etc)
    Donc le serveur récupère bien ces informations avec un recv() quand le client valide son inscription.
    Le problème se situe au niveau de la réponse du serveur, lorsque que le client clique par exemple pour valider son inscription, le serveur recoit bien les informations mais ici l'application client freeze et ne semble rien recevoir (readLine() bloquant au niveau du client ou send bloquant au niveau du serveur?)
    Par contre l'application ne freeze pas (je reçois quelque chose au niveau du client) lorsque, dans la routine du thread, j'enleve le commentaire //sortie=TRUE; mais le problème c'est que le thread se termine et qu'on forme le socket client et donc aucun dialogue possible par la suite.
    voici les extraits de code du serveur et du client (désolé c'est long)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    void* inscription(void *param)
    {
    	char buf [1024];
    	struct Client monClient;
    	int action, sd_client;
    	sd_client=*(int*)param;
    	bool sortie=FALSE;
    	while(!sortie)
    	{
    		memset(buf,0,sizeof(buf));
    		recv(sd_client,buf,sizeof(buf),0);
     
    		//fprintf(stdout,"buf-> %s",buf);	
    		char *Tab = (char *) malloc ((1024+1) * sizeof (char));
    		for (z = 0; z < 1024; z++)
    			Tab [z] = buf[z];
    		Tab [z+1] = '\0';
     
    		//action=atoi(strtok(Tab,"|"));	
    		action=atoi(Tab);
    		switch(action)
    		{
    			case 0: break;
    			case 1:
    				if(recv(sd_client,buf,sizeof(buf),0) != -1)
    				{
    					for (z = 0; z < 1024; z++)
    						Tab [z] = buf[z];
    					Tab [z+1] = '\0';
    					//fprintf(stdout,"%s","inscription");
    					monClient.Nom=strtok(Tab,"|");
    					monClient.Prenom=strtok(NULL,"|");
    					monClient.Adresse=strtok(NULL,"|");
    					monClient.Email=strtok(NULL,"|");
    					monClient.Telephone=strtok(NULL,"|");
    					monClient.IP=strtok(NULL,"|");
    					monClient.MP=strtok(NULL,"|");  
    					fprintf(stdout,"%s\n",monClient.Nom);
    					fprintf(stdout,"%s\n",monClient.Prenom);
    					fprintf(stdout,"%s\n",monClient.Adresse);
    					fprintf(stdout,"%s\n",monClient.Email);
    					fprintf(stdout,"%s\n",monClient.Telephone);
    					fprintf(stdout,"%s\n",monClient.IP);
    					fprintf(stdout,"%s\n",monClient.MP);
     
    					deja_inscrit=0;
    					for(i=0;i<nb_clients_inscrits;i++)
    					{
    						if(strcmp(Clients[i].Email,monClient.Email) == 0)
    						{
    							deja_inscrit=1;
    						}
    					}
     
    					if(deja_inscrit == 0)
    					{
    						nb_clients_inscrits++;
    						Clients=realloc(Clients,nb_clients_inscrits*sizeof(monClient));
    						Clients[nb_clients_inscrits-1]=monClient;
    						fprintf(stdout,"Inscription reussie pour %s\n",Clients[nb_clients_inscrits-1].Nom);
    						fprintf(stdout,"%s",msg);
    						strcpy(test,"Inscription reussie!");
    						//sortie=TRUE;
    					}
    					else
    					{
    						fprintf(stdout,"Inscription KO pour %s\n",monClient. Nom);
    						fprintf(stdout,"%s",msg);
    						strcpy(test,"Vous etes deja inscrit!");
    					}
     
    					fprintf(stdout,"Nombre d'inscrits : %d\n", nb_clients_inscrits);
    					for(i=0;i<nb_clients_inscrits;i++)
    					{
    						fprintf(stdout, "mail  : %s\n", Clients[i].Email);
    					}
     
     
    					//n=write(sd_client,test,strlen(test));
    					if(send(sd_client,test, strlen(test),0) == -1)
    					{
    						perror("erreur send");
    					}
    					/*if(n < 0)
    					{
    						perror("erreur write");
    					}
    					else
    					{
    						fprintf(stdout,"message envoye -> %s",test);
    					}*/
    				}
    					break;
    			case 2:
    				[...]
    				break;
    			case 3:
    				[...]
    				break;
    		}
    	}//fin du while
    	close(sd_client);
    	pthread_exit(0);
    }
    Ensuite dans le main() j'ai ça (je déclare un socket + bind + listen juste avant)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    	while(1) /* Si demande de connexion ouvre une socket pour celle-ci */
    	{
       	msgsock = accept(sock, (struct sockaddr *)&emis,&lemis);
       	if (msgsock < 0) perror("accept");
    		else 
    		{
    			if (getsockname (msgsock,(struct sockaddr *)&emis, &lemis) < 0)
    			{
      	 			perror ("getsockname"); close (sock); return 1;
    			}
    			/* ntohs conversion entiers format réseau to hote */
    			printf ("Socket TCP emetteur %s port #%d\n", inet_ntoa(emis.sin_addr.s_addr), ntohs (emis.sin_port));
    			if (pthread_create(&thread_inscription, NULL,inscription, &msgsock) == -1)
    			{
    	  			perror("Unable to create the thread");
    			}
     
     
    		}
     
    	}
    	close(sock);
    au niveau du client : "pred" me sert pour envoyer au serveur et "plec" me sert à lire ce qui vient du serveur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
       private void bt_valider_inscriptionActionPerformed(java.awt.event.ActionEvent evt) {
            String retour="";
     
            if(TestVariable(tf_nom.getText()) && TestVariable(tf_prenom.getText()) && TestVariable(tf_adresse.getText()) && TestVariable(tf_email.getText()) && TestVariable(tf_tel.getText()) && TestVariable(new String(tf_mdp.getPassword())))
            {
     
                try
                {
                    String ip="";
                    ip = InetAddress.getLocalHost().getHostAddress();
                    leClient=new structClient();
                    leClient.setAdresse(tf_adresse.getText());
                    leClient.setEmail(tf_email.getText());
                    leClient.setIP(ip);
                    leClient.setNom(tf_nom.getText());
                    leClient.setPrenom(tf_prenom.getText());
                    leClient.setTel(tf_tel.getText());
                    leClient.setMP(new String(tf_mdp.getPassword()));
                    pred.println(INSCRIPTION);
                    pred.println(leClient.getNom()+"|"+leClient.getPrenom()+"|"+leClient.getAdresse()+"|"+leClient.getEmail()+"|"+leClient.getTel()+"|"+leClient.getIP()+"|"+leClient.getMP());          // envoi d'un message   */
                    System.out.println(leClient.getNom()+"|"+leClient.getPrenom()+"|"+leClient.getAdresse()+"|"+leClient.getEmail()+"|"+leClient.getTel()+"|"+leClient.getIP()+"|"+leClient.getMP());
     
                        retour=plec.readLine();
                        System.out.println("retour: "+retour+"\n");
     
                    if(retour.equals("Vous etes deja inscrit!"))
                    {
                        bt_valider_inscription.setEnabled(true);
                        //Deconnexion();
                        //if(!Connexion())
                        //{
                            JOptionPane.showMessageDialog(null,"Serveur pas en ligne");
                        //}
                    }
                    if(retour.equals("Inscription reussie!"))
                    {
                        //bt_valider_inscription.setEnabled(false);
                       // ActionsInscription.setEnabled(false);
                       // ActionDesinscription.setEnabled(true);
                    }
                    JOptionPane.showMessageDialog(null,retour);
                }
     
                catch(UnknownHostException e) { System.err.println(e); }
                catch(IOException e) { }
     
     
            }
            else
            {
                JOptionPane.showMessageDialog(null,"Un des champs n'est pas rempli");
            }
     
        }

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char *Tab = (char *) malloc ((1024+1) * sizeof (char));
    		for (z = 0; z < 1024; z++)
    			Tab [z] = buf[z];
    		Tab [z+1] = '\0';
    Ca me paraît un peu suspect z+1 parce qu'en sortie de boucle ca vaut 1025 Tab[1025]=hors borne.

    je sais pas si recv ne place pas déja le /0 autant faire un calloc dans ce cas.


    Le send n'est pas bloquant au niveau du serveur mais cela peut échouer tu n'as pas un perror send qui s'execute ?

    Tu pourrais montrer comment tu déclares la variable test ?

    Pour la partie java il y a un forum où on pourrait mieux te répondre sinon il faut que tu montres comment tu construit ta variable plec.
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    Pour l'histoire du 1025 regarde le malloc...
    Je sais que c'est du bidouillage mais ça marche, là n'est pas le problème.

    Non je n'ai pas de perror au moment du send() non plus!

    Pour la variable test j'ai Pour le plec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     socket = new Socket("127.0.0.1", 9999);
                   System.out.println("SOCKET = " + socket);
     
                plec = new BufferedReader(
                                       new InputStreamReader(socket.getInputStream())
                                       );
    Le problème n'est pas là non plus puisque je reçois bien quelquechose au niveau du client (une boite de dialogue affiche "inscription réussie") lorsque dans mon code dans le "case 1:" j'enlève le commentaire Si je remets le commentaire (on sort jamais de la boucle, on écoute sans cesse dans le thread), le client freeze.

  4. #4
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    Pour l'histoire du 1025 regarde le malloc...
    Oui j'ai bien vu tu alloues 1024+1 octets donc des indices valides compris entre 0 et 1024 hors en sortant de ta boucle z=1024 et tu mets ton /0 à l'indice 1024+1 donc y'a un probléme
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    Ah bah oui j'avais meme pas fait gaffe...d'ailleurs c'est bizarre, ça marche puisque ça m'affiche bien les bonnes valeurs quand je découpe avec strtok

    Y'a peut être plus simple pour mettre les données d'un tableau de char dans un pointeur sur un char ?

  6. #6
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    Citation Envoyé par roms712
    Ah bah oui j'avais meme pas fait gaffe...d'ailleurs c'est bizarre, ça marche puisque ça m'affiche bien les bonnes valeurs quand je découpe avec strtok

    Dans la pratique cela pourrait avoir des conséquences plus grave et jouait sur la stabilité de ton système.Qui as dis qu'un programme qui marche etait exempt d'erreur ?


    Citation Envoyé par roms712
    Y'a peut être plus simple pour mettre les données d'un tableau de char dans un pointeur sur un char ?
    Dans ton cas memcpy mais ta méthode est valable aussi c'est juste que tu débordes un peu.


    Pour la freeze(il faudra expliquer ce que tu appeles freeze d'ailleurs) il faut voir ce qui se passe vraiment parce qu'au départ tu dis que le client ne reçoit rien (tu te demandes même si readline est blocant) et d'un autre côté tu dis que ton client java t'affiche bien ta boite de dialogue (inscription réussi) alors que son appel ne vient qu'aprés ton readline....
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par hegros
    Pour la freeze(il faudra expliquer ce que tu appeles freeze d'ailleurs) il faut voir ce qui se passe vraiment parce qu'au départ tu dis que le client ne reçoit rien (tu te demandes même si readline est blocant) et d'un autre côté tu dis que ton client java t'affiche bien ta boite de dialogue (inscription réussi) alors que son appel ne vient qu'aprés ton readline....
    Ouais en fait ça freeze pas lorsque j'affecte la variable sortie à TRUE dans le serveur --> je compile en mettant sortie=TRUE mais le problème c'est que ça fait sortir de la boucle du thread et le thread se termine puis fermeture du socket client. le client ne peut plus dialoguer.
    Ca freeze quand je mets en commentaire le code sortie=TRUE (pour que le thread soit sans cesse en écoute) puis je recompile et là le client quand je clique sur un bouton qui est sensé envoyer des données, le serveur recoit bien les données mais après ça freeze (les champs, les boutons ne sont plus visibles) et je suis obligé d'arrêter le programme avec netbeans.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    Quand je fais un fprintf après le recv, ça m'affiche en boucle "apres recv"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    		recv(sd_client,buf,sizeof(buf),0);
    		fprintf(stdout,"%s\n","apres recv");
    C'est pas censé etre bloquant le recv?


    De plus, je viens d'essayer de killer (ctr+C) le serveur au moment où le client freeze. Apres le kill, le client n'est plus bloqué et affiche bien ce qu'il est censé recevoir, donc ça doit venir d'une erreur au niveau du serveur.

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    C'est OK, en fait j'avais oublié les \n dans les fprintf
    et surtout que la chaine que j'envoyais ne contenait pas un \n à la fin car la fonction au niveau java du client, le readLine() attend une chaine qui se termine soit par \n, \t, ...

    Merci en tout cas.

  10. #10
    Membre confirmé Avatar de Lunixinclar
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2006
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 416
    Points : 489
    Points
    489
    Par défaut
    J'ai bien aimé ton post, intéressant. C'est du code propre.

    Question: pourquoi ne pas faire le serveur lui aussi en java?

    Quelques suggestions:
    • Dans inscription() attention au malloc dans la boucle. Surtout pour un serveur qui peut tourner plusieurs jours. En clair, libérer Tab dès qu'on n'en a plus besoin. Aussi, vérifier que l' allocation a réussi.
    • Le memset() peut être évité, hegros l' a évoqué: soit calloc, soit un simple
      buf[machin]='\0'; <-plus rapide que memset non?
      Je te laisse découvrir d'ou sort exactement la variable machin, voir plus bas.

    • En remplaçant le strcpy(test, msg) par sprintf(), on pourrait récupérer la longueur de la chaine, qui aurait double utilité pour le

      if(send(sd_client,test, strlen(test),0) == -1)

      1) éviterait de reparcourir la chaîne par le strlen(),
      2) catcherait mieux les erreur sur le send:

      if(send(sd_client, test, len, 0) != len) perror("send");

      Ok je pinaille, mais plus le serveur sera rapide, plus il sera à même de bien se comporter en situations de stress.

    • Dans le main, vérifier aussi que le close() réussit. Toutes ces vérifications faciliteront la suite des évènements, en particulier si le code grossit: ton exemple montre bien qu'un seul grain de sel peut faire vasciller l' ensemble.

    Bonne prog

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par Lunixinclar
    J'ai bien aimé ton post, intéressant. C'est du code propre.
    Pourtant le C c'est pas mon truc et j'ai l'impression de coder comme un cochon.

    Citation Envoyé par Lunixinclar
    Question: pourquoi ne pas faire le serveur lui aussi en java?
    J'aurais bien aimé aussi mais c'est mon prof. qui a voulu ça. On avait uniquement le choix du langage pour le client.

    Citation Envoyé par Lunixinclar
    Quelques suggestions:
    • Dans inscription() attention au malloc dans la boucle. Surtout pour un serveur qui peut tourner plusieurs jours. En clair, libérer Tab dès qu'on n'en a plus besoin. Aussi, vérifier que l' allocation a réussi.
    • Le memset() peut être évité, hegros l' a évoqué: soit calloc, soit un simple
      buf[machin]='\0'; <-plus rapide que memset non?
      Je te laisse découvrir d'ou sort exactement la variable machin, voir plus bas.

    • En remplaçant le strcpy(test, msg) par sprintf(), on pourrait récupérer la longueur de la chaine, qui aurait double utilité pour le

      if(send(sd_client,test, strlen(test),0) == -1)

      1) éviterait de reparcourir la chaîne par le strlen(),
      2) catcherait mieux les erreur sur le send:

      if(send(sd_client, test, len, 0) != len) perror("send");

      Ok je pinaille, mais plus le serveur sera rapide, plus il sera à même de bien se comporter en situations de stress.

    • Dans le main, vérifier aussi que le close() réussit. Toutes ces vérifications faciliteront la suite des évènements, en particulier si le code grossit: ton exemple montre bien qu'un seul grain de sel peut faire vasciller l' ensemble.

    Bonne prog
    Oki bah merci! je verrai si j'ai le temps de changer tout ça, on doit rendre tout ça la semaine prochaine donc bon

  12. #12
    Membre confirmé Avatar de Lunixinclar
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2006
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 416
    Points : 489
    Points
    489
    Par défaut
    Hmm ton prof c'est le genre à porter une chaussette blanche et l' autre noire non? Demander à un programmeur Java d'écrire un serveur en C, c'est un peu comme demander à celui qui a peint la Joconde de faire de la peinture en bâtiment. Si pour une raison ou une autre le client n'envoie pas le code 0,1,2, ou 3, le serveur se met à faire du malloc en rafale

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    Bah j'avais pas envie de faire le client C en console, ni même en interface graphique. Donc bon on a choisi java, puis bon comme ça, ça nous fait voir le fonctionnement dans 2 langages différents.

    Si pour une raison ou une autre le client n'envoie pas le code 0,1,2, ou 3, le serveur se met à faire du malloc en rafale
    oui oui on y a eu droit

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Programmation Socket et Thread
    Par seco102 dans le forum Threads & Processus
    Réponses: 4
    Dernier message: 24/05/2012, 16h29
  2. Réponses: 11
    Dernier message: 17/05/2012, 10h38
  3. [Jeu] - Programmation réseau <sérialisation,sockets,threads>
    Par ixabro dans le forum Développement
    Réponses: 5
    Dernier message: 02/02/2012, 22h18
  4. Pour débuter en programmation réseau
    Par durnambule dans le forum Développement
    Réponses: 3
    Dernier message: 20/06/2004, 22h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo