I am building a client-server socket
simulation in C
I accept a TCP connection
from a client then the client sends a message to my server. I am successfully receiving the message, then I iterate through my array
of structs
to look for a string match
struct Mapping
{
char key[6];
char value[8];
} MapElement;
int main
{
char buf[BUFSIZE]; /* BUFSIZE 2048 */
int size = 4;
struct Mapping serverMap[size];
initialize_server_map(serverMap); /* This method works, so not displaying in SO */
/* ... socket stuff (this works as seen from print statements) */
recvlen = recv(rqst, buf, BUFSIZE, 0);
printf("The received length is %d\n", recvlen);
printf("The buf is: %s\n", buf);
if (recvlen > 0) {
buf[recvlen] = 0;
printf("The Server 2 has received a request with key %s\n", buf);
char* buf_for_token[10];
strcpy(buf_for_token, buf);
const char s[2] = " ";
char *token;
token = strtok(buf_for_token, s);
token = strtok(NULL, s);
int found = 0;
for(int i = 0; i < sizeof(serverMap) / sizeof(struct Mapping); i++) {
printf("Token: %sServerMapEntry: %s\n", token, serverMap[i].key);
printf("Compare: %d\n", strcmp(serverMap[i].key, token));
if (strcmp(serverMap[i].key, token) == 0) {
printf("What is wrong?!?! Why is this not printing?!\n");
found = 1;
strcpy(post, "POST ");
strcat(post, serverMap[i].value);
if (send(rqst, post, strlen(post), 0) < 0) {
perror("sendto");
}
break;
}
}
}
}
My output is:
The received length is 9
The buf is: GET key05
The Server 2 has received a request with key GET key05
Token: key05ServerMapEntry: key05
Compare: 0
I cannot understand why the next print statement is not printing. My program is just hanging forever. :(
There is a bug here:
char* buf_for_token[10];
strcpy(buf_for_token, buf);
How do you manage to even compile this program?
buf_for_token
is an array of pointers to char
, it should just be an array of char
, and make it large enough:
char buf_for_token[BUFSIZE];
strcpy(buf_for_token, buf);
This buffer should be as large as the receiving buffer, and as mentioned in the comments, you should pass 1
less than its size to recv
in order to keep one extra byte for the '\0'
you force at the end:
recvlen = recv(rqst, buf, sizeof(buf) - 1, 0);
In the for
loop, use size
instead of sizeof(serverMap) / sizeof(struct Mapping)
, or sizeof(serverMap) / sizeof(*serverMap)
.
As to why the printf("What is wrong?!?! Why is this not printing?!\n");
does not output anything, try fflush(stdout);
just after the printf()
to make sure it is not just a buffering issue.
Or it may also be that you are not posting the exact code... post
is not defined, and the function prototype is missing some body parts:
int main
{
Finally, if your sockets are TCP, be aware that data sent by the client may be received by the server in chunks of a different size, smaller of larger. The only guarantee is the order of the byte stream. You should not rely on the fact that most of the time you receive a full line. Network congestion or other conditions beyond yoyr control may cause packets to get sliced and received in small chunks or combined in larger chunks containing several lines... To handle this potential situation in the server you should bufferize the data and handle one line at a time.