lufork lufork - 3 months ago 8
Linux Question

How to send and receive newline character over sockets in a client server model?

I am trying to learn client server model in Linux and I have setup two C files namely server.c and client.c. These are the code snippets that I seem to have problems with.

server.c code snippet

char* message = "<query>\n";
write(client_socket_filedescriptor, message, sizeof(message));


client.c code snippet

char* message = "<query>\n";
read(socket_filedescriptor, buffer, sizeof(buffer));
printf("%s", buffer);
printf("\n\n");
printf("%s", message);


Now when I run my server and then when I run my client, I expect the printf statements to print the same strings that is
<query>\n
, but I keep getting different outputs for
buffer
and
message
variables.

The output looks a bit like this when I run client code.

Output image

As you see, these two strings are different. I am trying to simulate a typical TCP handshake and I want to make sure that these two strings are same and then client will start writing or doing something with that server. But I am having this trivial problem. Could anyone tell my how to resolve it? I plan to use strcmp to compare buffer and message variables, but as it stands now, strcmp doesn't return 0 since these are different strings afterall.

EJP EJP
Answer

You are ignoring the count returned by read(). It can be -1, indicating an error, or zero, indicating end of stream, or a positive number, indicating how many bytes were received. You cannot assume that read() fills the buffer, or that a single send() or write() corresponds to a single recv() or read().

In detail:

write(client_socket_filedescriptor, message, sizeof(message));

You are only sending four bytes, the size of the pointer. And you're ignoring the return value. It should be

int count = write(client_socket_filedescriptor, message, strlen(message));
if (count == -1)
    perror("write"); // or better

char* message = "<query>\n";

read(socket_filedescriptor, buffer, sizeof(buffer));

That should be

int count = read(socket_filedescriptor, buffer, sizeof(buffer));
if (count == -1)
    perror("read"); // or better
else if (count == 0)
    ; // end of stream: the peer has disconnected: close the socket and stop reading
else

Back to your code:

printf("%s", buffer);

That should be

printf("%.*s", count, buffer);

I plan to use strcmp()

You should plan to use strncmp(), with count above as the length parameter. In any case you can't assume the input ends with a null unless you (a) ensure you send the null, which you aren't, and (b) write a read loop that stops when you've read it.