Programmation du socket C, le tampon d’envoi du serveur ne semble pas être effacé

Je suis très nouveau en programmation de socket et j’ai des problèmes avec elle. Je souhaite implémenter un serveur qui répond en fonction d’une requête client donnée. Dans mon cas, GET, HEAD ou une autre erreur. Considérer le code suivant

Si j’imprime la réponse avant d’appeler send() (voir le code côté serveur ci-dessous), le message est correct. Mais disons du client que j’envoie

  1. OBTENIR
  2. TÊTE
  3. OBTENIR
  4. tester
  5. OBTENIR

, la réponse imprimée côté client est

 You want GET You want HEAD You want GETD HTTP/1.1 400 Bad Request You want GET Bad Request 

Il semble donc que le message envoyé par le serveur est en quelque sorte “écrasé”, mais comment cela peut-il être évité? Est-il possible de “vider le tampon du serveur” si tel est le problème?

Voici le code complet côté serveur

 #include  #include  #include  #include  #include  #include  #include  #define BUFSIZE 1024 #define MAXPENDING 100 int main(){ char get[] = "GET"; char head[] = "HEAD"; int serverSocket = socket(PF_INET, SOCK_STREAM, 0); struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(8080); serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); memset(&serverAddress.sin_zero, '\0', 8); bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)); listen(serverSocket, MAXPENDING); for(;;){ struct sockaddr_in clientAddress; int clientAddressLength = sizeof(clientAddress); int clientSocket; clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, &clientAddressLength); char buf[BUFSIZE]; int bytesRec; bytesRec = recv(clientSocket, buf, BUFSIZE, 0); while(bytesRec > 0){ char *result; result = strtok(buf, " "); printf("result %s\n", result); if(strcmp(&buf, &get) == 0){ char answer[] = "You want GET"; send(clientSocket, answer, strlen(answer), 0); }else{ if(strcmp(&buf, &head) == 0){ char answer[] = "You want HEAD"; send(clientSocket, answer, strlen(answer), 0); }else{ char answer[] = "HTTP/1.1 400 Bad Request"; send(clientSocket, answer, strlen(answer), 0); } } bytesRec = recv(clientSocket, buf, BUFSIZE, 0); } return 0; } 

et le côté client

 #include  #include  #include  #include  #include  #include  #include  int main(){ int clientSocket = socket(PF_INET, SOCK_STREAM, 0); struct sockaddr_in clientAddress; clientAddress.sin_family = AF_INET; clientAddress.sin_port = 0; clientAddress.sin_addr.s_addr = htonl(INADDR_ANY); memset(&clientAddress.sin_zero, '\0', 8/*sizeof(clientAddress.sin_zero)*/); bind(clientSocket, (struct sockaddr*)&clientAddress, sizeof(clientAddress)); struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(8080); serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1"); memset(&serverAddress.sin_zero, '\0', 8); if(connect(clientSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == -1){ printf("error in connecting!\n"); return 0; } char* serverReply[1024]; for(;;){ char request[100]; printf("Enter your request: "); scanf("%s", &request); send(clientSocket, request, strlen(msg), 0); if(recv(clientSocket, serverReply, strlen(serverReply), 0) < 0){ printf("failure in receiving from server!\n"); }else{ printf("%s\n", serverReply); } } close(clientSocket); return 0; } 

 send(clientSocket, request, strlen(msg), 0); 

Cela envoie uniquement les caractères de chaîne et n’inclut pas la valeur NULL de fin. Le tampon de réception ne termine pas la chaîne reçue côté serveur.

C’est pourquoi vous voyez toujours le caractère ‘D’ du message précédent.

 You want GETD <-- 'D' is from the previous 'HEAD' 

Soit terminer la chaîne reçue sur le serveur,

 buf[bytesRec] = '\0'; 

Edit: comme @Zan le fait remarquer, ne faites pas ceci:

ou envoyer le terminateur NULL à partir du client.

 send(clientSocket, request, strlen(msg) + 1, 0); 

Votre strcmp() dans if sont faux

(1) au lieu de buf, vous devez comparer le result tel que je peux le comprendre grâce à votre question, faites comme: (vous dites dans un commentaire que le résultat est imprimé en tant que GET)

 if(strcmp(result, get) == 0){ 

(2) Comme @phihag a répondu, cela devrait être

 if(strcmp(buf, get) == 0){ ^ ^remove & 

erreur similaire que vous avez sur chaque strcmp (), parce que buf , get , head sont tous des tableaux de charte.

(3) recv() ne termine pas le tampon de lecture, il est donc préférable d’append null ( \0 ) avant de l’ utiliser ( comme je peux le constater, vous utilisez buff comme chaîne ).

fais comme:

 bytesRec = recv(clientSocket, buf, BUFSIZE, 0); buf[bytesRec] = '\0' 

BUFSIZE-1 vous devriez lire seulement les octets BUFSIZE-1 restants pour '\0' symbole null '\0' comme:

 ytesRec = recv(clientSocket, buf, BUFSIZE-1, 0); buf[bytesRec] = '\0'