Reputation: 5052
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
, 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;
}
Upvotes: 3
Views: 4076
Reputation: 8160
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);
Upvotes: 5
Reputation: 58291
Your strcmp()
in if are wrong
(1) instead of buf you need to compare with result
as I can understand from you question, do like: (you says in comment that result printed as GET)
if(strcmp(result, get) == 0){
(2) As @phihag answered it should be
if(strcmp(buf, get) == 0){
^ ^remove &
similar error you have on every strcmp(), because buf
, get
, head
all are charter arrays.
(3) recv()
doesn't terminates the read buffer so its better to add null (\0
) before you work with it (as i can notice you are using buff as string)
do like:
bytesRec = recv(clientSocket, buf, BUFSIZE, 0);
buf[bytesRec] = '\0'
infect you should read only BUFSIZE-1
bytes left one for null '\0'
symbol like:
ytesRec = recv(clientSocket, buf, BUFSIZE-1, 0);
buf[bytesRec] = '\0'
Upvotes: 2