C socket programming, server send buffer seems not to be cleared
c, sockets
Solution
send(clientSocket, request, strlen(msg), 0);
This sends only the string characters and does not include the terminating NULL. The receive buffer does not terminate the received string on the server side.
This is why you are still seeing the 'D' character from the previous message.
You want GETD <-- 'D' is from the previous 'HEAD'
Either terminate the received string on the server,
buf[bytesRec] = '\0';
Edit: as @Zan points out, don't do this:
or send the NULL terminator from the client.
send(clientSocket, request, strlen(msg) + 1, 0);
Problem
I am very new to socket programming and I have troubles with it. I want to implement a server that answers depending on a certain client request. In my case, either GET, HEAD or an error else. Consider following code If I print the answer before calling `send()` (see server side code below), the message is correct. But let's say from the client I send - GET - HEAD - GET - test - GET , the answer printed from the client side is ``` You want GET You want HEAD You want GETD HTTP/1.1 400 Bad Request You want GET Bad Request ``` So it seems like that the message sent from the server is kind of 'overwritten', but how is this avoidable? Is it possible to 'clear the server buffer' if that is the problem at all? Here is the full server side code ``` #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #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; } ``` and the client side ``` #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> 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; } ```