Bonsoir à tous,
Voilà donc j'ai un projet dont la base est de créer une sorte de "chat", le problème est le suivant (par étapes) :
- Je commence par créer une application serveur et une application client, et faire envoyer un message tapé au clavier de l'application serveur à l'application client qui le print dans la console. Ça c'est OK
- Le truc c'est qu'un chat c'est dans deux sens, donc je suis un tutoriel sur les threads pour pouvoir envoyer ET recevoir à partir des deux applications. Donc je ne change rien à mon code à part que j'ajoute chez le client un thread pour envoyer et chez le serveur un thread pour recevoir. Je compile et PAF : maintenant le client envoie et le serveur reçoit, mais dans l'autre sens maintenant ça ne marche plus, alors que j'y ai rien touché...
C'est surement un truc tout "con" (ça m'arrive tout le temps) mais je trouve pas ...
Le code de l'application serveur :
Le code de l'application client :
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121 #if defined (WIN32) #include <winsock2.h> typedef int socklen_t; #elif defined (linux) #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 #define closesocket(s) close(s) typedef int SOCKET; typedef struct sockaddr_in SOCKADDR_IN; typedef struct sockaddr SOCKADDR; #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #define PORT 23 int main(void) { #if defined (WIN32) WSADATA WSAData; int erreur = WSAStartup(MAKEWORD(2,2), &WSAData); #else int erreur = 0; #endif SOCKET sock; SOCKADDR_IN sin; SOCKET csock; SOCKADDR_IN csin; char buffer[100] = "Bonjour !"; socklen_t recsize = sizeof(csin); int sock_err; pthread_t thread; void* sock_receive(SOCKET sock); /* Si les sockets Windows fonctionnent */ if(!erreur) { sock = socket(AF_INET, SOCK_STREAM, 0); /* Si la socket est valide */ if(sock != INVALID_SOCKET) { printf("La socket %d est maintenant ouverte en mode TCP/IP\n", sock); /* Configuration */ sin.sin_addr.s_addr = htonl(INADDR_ANY); /* Adresse IP automatique */ sin.sin_family = AF_INET; /* Protocole familial (IP) */ sin.sin_port = htons(PORT); /* Listage du port */ sock_err = bind(sock, (SOCKADDR*)&sin, sizeof(sin)); /* Si la socket fonctionne */ if(sock_err != SOCKET_ERROR) { /* Démarrage du listage (mode server) */ sock_err = listen(sock, 5); printf("Listage du port %d...\n", PORT); /* Si la socket fonctionne */ if(sock_err != SOCKET_ERROR) { /* Attente pendant laquelle le client se connecte */ printf("Patientez pendant que le client se connecte sur le port %d...\n", PORT); csock = accept(sock, (SOCKADDR*)&csin, &recsize); printf("Un client se connecte avec la socket %d de %s:%d\n", csock, inet_ntoa(csin.sin_addr), htons(csin.sin_port)); pthread_create(&thread, NULL, sock_receive(csock), NULL); printf("Debut des transmissions, que voulez vous envoyer?\n"); while (strstr(buffer, "/stop")==NULL) { fgets(buffer, 100, stdin); sock_err = send(csock, buffer, 100, 0); if(sock_err != SOCKET_ERROR) printf("Chaine envoyée : %s\n", buffer); else printf("Erreur de transmission\n"); } printf("fin des transmissions\n"); /* Il ne faut pas oublier de fermer la connexion (fermée dans les deux sens) */ shutdown(csock, 2); } } /* Fermeture de la socket */ printf("Fermeture de la socket...\n"); closesocket(sock); pthread_cancel(thread); printf("Fermeture du serveur terminee\n"); } #if defined (WIN32) WSACleanup(); #endif } /* On attend que l'utilisateur tape sur une touche, puis on ferme */ getchar(); return EXIT_SUCCESS; } void* sock_receive(SOCKET sock) { char buffer2[100]; while(1) { if(recv(sock, buffer2, 100, 0) != SOCKET_ERROR) printf("Recu : %s\n", buffer2); } }
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 #if defined (WIN32) #include <winsock2.h> typedef int socklen_t; #elif defined (linux) #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 #define closesocket(s) close(s) typedef int SOCKET; typedef struct sockaddr_in SOCKADDR_IN; typedef struct sockaddr SOCKADDR; #endif #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define PORT 23 int main(void) { #if defined (WIN32) WSADATA WSAData; int erreur = WSAStartup(MAKEWORD(2,2), &WSAData); #else int erreur = 0; #endif SOCKET sock; SOCKADDR_IN sin; char buffer[100] = ""; char IP[30] = ""; pthread_t thread; void* sock_send(SOCKET sock); /* Si les sockets Windows fonctionnent */ if(!erreur) { /* Création de la socket */ sock = socket(AF_INET, SOCK_STREAM, 0); /* Configuration de la connexion */ printf("IP ? (127.0.0.1 pour ce pc)"); fgets(IP, 30, stdin); sin.sin_addr.s_addr = inet_addr(IP); sin.sin_family = AF_INET; sin.sin_port = htons(PORT); /* Si l'on a réussi à se connecter */ if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR) { printf("Connection à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port)); /* Si l'on reçoit des informations : on les affiche à l'écran */ printf("debut de la reception\n"); pthread_create(&thread, NULL, sock_send(sock), NULL); while(strstr(buffer, "/stop")==NULL) { if(recv(sock, buffer, 100, 0) != SOCKET_ERROR) printf("Recu : %s\n", buffer); } } /* sinon, on affiche "Impossible de se connecter" */ else { printf("Impossible de se connecter\n"); } printf("fin de reception\n"); pthread_cancel(thread); /* On ferme la socket */ closesocket(sock); #if defined (WIN32) WSACleanup(); #endif } /* On attend que l'utilisateur tape sur une touche, puis on ferme */ getchar(); return EXIT_SUCCESS; } void* sock_send(SOCKET sock){ char buffer2[100] = ""; int sock_err; while(1){ fgets(buffer2, 100, stdin); sock_err = send(sock, buffer2, 100, 0); if(sock_err != SOCKET_ERROR) printf("Chaine envoyée : %s\n", buffer2); else printf("Erreur de transmission\n");}}
Merci d'avance !!!!!!
Édit :
Une petite question moins importante, pourquoi la connexion marche très bien en réseau local classique mais pas quand j'essaie de me connecter via un réseau "hamachi" ?
Partager