Edit: I honestly have no idea where the error is happening so I'll just add most of the relevant code, not sure if any of this helps
so basically I have two basic server & client processes. The user specifies a command, the client process then sends the length of the message to the server, the server executes the command and sends back a message length of the response.
This works well on the first command (I tried two ls -la in a row), the value is 1028 on the first command(correct value), and incorrectly 1685223288(in the client) on the second command
The write is done with the following code:
server_handler() {
char str[5000];
char * token = NULL;
unsigned long totalSize = 0;
str[0] = "\0";
totalSize = htonl(totalSize); // Correct size already calculate
if((result = write(clientFD, (char *) &totalSize, sizeof(totalSize)) < 0))
{
printf("Failed sending size to client\n");
exit(-1);
}
//Here the server starts sending the results to the client
token = strtok(str, "\n"); // str array contains the results
while(token != NULL)
{
token[strlen(token)] = '\n';
write(clientFD, token, strlen(token));
token = strtok(NULL, "\n);
}
The read is done in the client process in the following way:
static void handle_reply()
{
char * revBuf = 0;
unsigned long int bytesRead = 0;
unsigned long bufferlen = 0;
while(1)
{
result = read(socketFD, (char *) &bufferlen, sizeof(bufferlen));
bufferlen = ntohl(bufferlen);
recvBuf = malloc(bufferlen);
//Here client starts reading results
while(bytesread < bufferlen)
{
result = read(socketFD, recvBuf, bufferlen);
printf("recvBuf: %s\n", recvBuf);
bytesRead = strlen(recvBuf) + bytesRead;
}
free(recvBuf);
bufferlen = 0;
client_handler(); //calls Function that asks for new command
}
}
My question: Why am I receiving the wrong values on commands after the first one?, I have verified that totalSize has the correct value on server side in both cases with a print. Something must be going wrong in the write/read?
I also printed htonl(totalSize) on the server and it is 67371008. However the value received on the client side is 2021093988 before ntohl.
The following code isn't going to work correctly, because you call strlen
again after modifying the string.
token = strtok(str, "\n");
while(token != NULL)
{
token[strlen(token)] = '\n';
write(clientFD, token, strlen(token));
token = strtok(NULL, "\n");
}
To illustrate, assume that str
is initially "hello\nworld\n"
. In hex that's
68 65 6c 6c 6f 0A 77 6f 72 6c 64 0A 00
^---- the first newline
After the strtok
it will be
68 65 6c 6c 6f 00 77 6f 72 6c 64 0A 00
^---- strtok changed it to a NUL
After the line token[strlen(token)] = '\n'
it will be
68 65 6c 6c 6f 0A 77 6f 72 6c 64 0A 00
^---- you changed it back to a newline
so now the strlen
in the write
will return 12, so the write
will send 12 bytes, not 6 like you expect. This can be fixed by calling strlen
once, like this
token = strtok(str, "\n");
while(token != NULL)
{
size_t length = strlen(token);
token[length] = '\n';
write(clientFD, token, length);
token = strtok(NULL, "\n");
}