简体   繁体   中英

How does the read function in c knows when to stop reading from a client socket?

I programmed a client and a server in C to test data transfer with sockets. Basically the server waits for a connection, accepts it and calls a read() function to the client file descriptor like this:

while (read(clisock_fd, client_message, 20000) > 0) {
    puts(client_message);
}

And in the client program, I only send one message with write() , like this:

write(sockfd, my_message, strlen(my_message));

What i can't figure out is, if the write() function sends 8 bytes, and the read() function reads them once, how does it know that it is time to stop waiting for any other messages?

If I send 3000 bytes, for example, the read function reads 1448 bytes, then it reads the rest, and then it just knows its over and stops. How?

It never waits after having read at least one byte. Your hardware has buffers, your kernel has buffers. The 8 bytes become available to the userspace process at once . In fact, they are transferred in one ethernet frame, because there are buffers on the writing side, too.

It seems that both questions:

  • What I can't figure out is, if the write() function sends 8 bytes, and the read() function reads them once, how does it know that it is time to stop waiting for any other messages?

  • If I send 3000 bytes, for example, the read() function reads 1448 bytes, then it reads the rest, and then it just knows its over and stops. How?

have the same answer for the provided source code.

The related part of the appropriate man-page:

RETURN VALUE

On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal. On error, -1 is returned, and errno is set appropriately. In this case it is left unspecified whether the file position (if any) changes.

-- read(2) .

So, for the given source code when the read() function returns non-positive number (zero or negative number), the condition of the while-loop becomes false . More likely after sending the "message", the Sender closes the connection ( close() function call) and the Receiver "knows the end-of-the-message" because the Receiver's read() function call returns zero.

Notes

  1. Please introduce checking the return value of both read() and write() function calls. The functions do not guarantee to read/write the specified number of bytes at once (at one call).

  2. The article TCP/IP client-server application: exchange with string messages, Sergey Brunov might be useful. The article describes the idea of "message boundary" and provides an example of its implementation.

The rule is quite simple. For a blocking socket, the read will wait until there is some data to read, that could be 1 byte or 1MB. The kernel will then copy over as much data at the kernel has in its internal buffer, or the number of bytes requested, whichever is the smaller. and The read will immediately return after this without waiting for further data. The return value of the read reports the actual number of bytes read.

You program works because you are on a fast connection and it so happens that you are writing in sensible chunks. However you might find once you roll out your program in the read world your program crashes. This is because your read might return only part of the string without the null terminator. When you call puts the buffer will overrun and you may crash (or worse).

So if as in your case, your protocol dictates that the data stream must end with a null, you will need to parse the returned data to see if it contains a null. For the reason, I prefer protocols that specify the length of data being sent before the data is actually sent. Make processing much simpler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM