C socket - consecutive read/write, what happens? - c

In a server/client in C, TCP, what happens if I do consecutive read/write in my program? Is this possibile, or do I've always to follow the structure "client write->server read->server write->client read"?
Is it possible to do something like this? Or is it possible that data from the 3rd write in the server are received from the 2nd read in the client, and other bad things like this?
client.c
write (1)
read (2)
read (3)
read (4)
server.c
read (1)
write (2)
write (3)
write (4)

TCP transfers a data stream.
So N calls to write could result in M calls to read (with N>0 and M>0 and N<=number of bytes transferred and M<=number of bytes transferred).
The order in which the bytes were send will however be preserved between the various writes and reads involved.
As a direct consequence to this you cannot just use the plain number of calls to write and read to synchronise processes. You need to add for example the number of bytes to be transferred by each step.
To cut it short: You need an application level protocol on top of the TCP stream.

Yes, this is possible. reads will block (by default) until data are available to read on the socket. There's no need to try to arrange for reads and writes in a particular order, your program will just wait until there is something to read before the read() call returns.
Your code will result in this:
Server blocks in read()
Client write()s
Client blocks in read()
Server receives data, read() returns
Server write()s three times
Client receives data, read(1) returns
Client's read(2) is called and returns as soon as data arrive
Client's read(3) is called and returns as soon as data arrive
On a really fast link it's possible that the server write()s and the client read()s happen at roughly the same time, maybe even interleaved, but the server write()s will always be in order and the client's read()s will always be in order.
Data ordering is preserved if the sockets are SOCK_STREAM, eg. TCP or UNIX sockets like you're asking about.
So read(2) will always return the data written in write(2) for a TCP socket.
If you used a UDP socket (SOCK_DGRAM's default) you might find that the messages are received out-of-order or not at all.

Related

C socket atomic non-blocking read

I'm implementing a TCP/IP server application which uses epoll in edge-triggered mode and does non-blocking socket operations. The clients are using simple blocking operations without epoll.
I don't see how "atomic reads" can be implemented on the server side. To explain what I mean about "atomic read", see this example with simple blocking operations:
Both the client and the server are using 64K buffers. (On application level. They don't change the kernel level socket buffers.)
Client writes 12K data with a single write operation.
Server reads it. In this case it always reads the whole 12K when the buffers are the same. So it can't read only the half of it. This is what I call "atomic".
But in the case of epoll + non-blocking operations this can happen:
Both the client and the server are using 64K buffers. (On application level. They don't change the kernel level socket buffers.)
Client writes 12K data with a single write operation.
6K arrives to the server
epoll tells the application that data arrived to the socket
the application reads the 6K into the buffer using a non-blocking operation.
When repeating the read, it returns EAGAIN / EWOULDBLOCK.
In this case the read is not "atomic". It is not guarantied that when the data was written with a single write operation, then the read will return the whole, in one piece.
Is it possible to know when the data is partial? I know that one solution is to always append the data size to the beginning, or another could be to always close and re-open the connection, but I don't wanna do these: because I think the kernel must know that not the full "package" (how is that unit called BTW?) arrived, since it guaranties atomicity for the blocking operations.
Many thanks!
TCP is stream based and not message oriented. Even in case of blocking socket, you cannot be guaranteed that what the application sends would go as is on the wire in one go. TCP will decide its own course.
So, it is up to the application to do "atomic" read of it wishes. For example:
The application protocol should dictate that the message should be prepended by the length bytes. The length bytes inform the peer the size of the application data of interest. Of course, the application should be aware of when the two byte length indicator begins.
[2 byte msg length][Data bytes of interest]
Based on this information the application doing read should take action. It should be polling the socket until it receives all bytes as indicated by the msg length bytes. Only then process the data.
If you need "atomic" read and not partial read you can use MSG_PEEK flag in recv. This shall not remove the data from the socket buffer. Application peeks into the socket, see if required number of data is in socket buffer based on return value.
ret = recv(sd, buf, MAX_CALL_DATA_SIZE, MSG_PEEK);

Will read (socket) block until the buffer is full?

I wrote a simple C socket program that sends an INIT package to the server to indicate to prepare a text transfer. The server does not sends any data back at that time.
After sending the INIT package the client sends a GET package and waits for chunks of data from the server.
So every time the server receives a GET package it will send a chunk of data to the client.
So far so good. The buffer has a size of 512 bytes, a chunk is 100 Bytes plus a little overhead big.
But my problem is that the client does not receive the second message.
So my guess is that read() will blpck until the buffer is full. Is that right or what might be the reason for that?
It depends. For TCP sockets read may return before the buffer is full, and you may need to receive in a loop to get a whole message. For UDP sockets the size you read is typically the size of a single packet (datagram) and then read may block until it has read all the requested data.
The answer is no: read() on a tcp/ip socket will not block until the buffer has the amount of data you requested. read() will return immediately in all cases if any data is available, even if your socket is blocking and you've requested more data than is available.
Keep in mind that TCP/IP is a byte stream protocol and you must treat it as such. The interface is under no obligation to transmit your data together in a single packet, as long as it is presented to you in the order you placed it in the socket.
The answer is no , read is not blocking call , You can refer below points to guess the error
Several Checkpoints you can find :
Find out what read is returning at the second time .
memset the buffer every time in while before recv
use fflush(stdout) if not able to output.
Make sure all three are present . if problem not solved yet .please post source code here

blocking recv() that receives no data (TCP)

I'm attempting to write a simple server using C system calls that takes unknown byte streams from unknown clients and executes specific actions depending on client input. For example, the client will send a command "multiply 2 2" and the server will multiply the numbers and return the result.
In order to avoid errors where the server reads before the client has written, I have a blocking recv() call to wait for any data using MSG_PEEK. When recv detects data to be read, I move onto non-blocking recv()'s that read the stream byte by byte.
Everything works except in the corner case where the client sends no data (i.e. write(socket, "", 0); ). I was wondering how exactly I would detect that a message with no data is sent. In this case, recv() blocks forever.
Also, this post pretty much sums up my problem, but it doesn't suggest a way to detect a size 0 packet.
What value will recv() return if it receives a valid TCP packet with payload sized 0
When using TCP at the send/recv level you are not privy to the packet traffic that goes into making the stream. When you send a nonzero number of bytes over a TCP stream the sequence number increases by the number of bytes. That's how both sides know where the other is in terms of successful exchange of data. Sending multiple packets with the same sequence number doesn't mean that the client did anything (such as your write(s, "", 0) example), it just means that the client wants to communicate some other piece of information (for example, an ACK of data flowing the other way). You can't directly see things like retransmits, duplicate ACKs, or other anomalies like that when operating at the stream level.
The answer you linked says much the same thing.
Everything works except in the corner case where the client sends no data (i.e. write(socket, "", 0); ).
write(socket, "", 0) isn't even a send in the first place. It's just a local API call that does nothing on the network.
I was wondering how exactly I would detect that a message with no data is sent.
No message is sent, so there is nothing to detect.
In this case, recv() blocks forever.
I agree.
I have a blocking recv() call to wait for any data using MSG_PEEK. When recv detects data to be read, I move onto non-blocking recv()'s that read the stream byte by byte.
Instead of using recv(MSG_PEEK), you should be using select(), poll(), or epoll() to detect when data arrives, then call recv() to read it.

c select() reading until null character

I am implementing a proxy in c and am using select() to not block on I/O. There are multiple clients connecting to the proxy, so I include the socket descriptor # in my messages so that I know to which socket to forward a reply message from the server.
However, sometimes read() will not receive the full message up to the null character, but will send the rest of the message on the next round of select(). I would like to receive the full message at once so that I will know which socket to forward the reply to (buffering will not work, since I don't know which message belongs to which when there are multiple clients). Is there a way to do this without blocking on read while waiting for a null character to arrive?
There is no such thing as a message in TCP. It is a byte stream protocol. You write bytes, it sends bytes, you read bytes. There is no guarantee how many bytes you will receive at any one time and there is no guaranteed association between the amount of data written by a single write and read by a single read. If you want messages you must implement them yourself. Any given read may read zero, one, or more bytes, up to the length of the buffer. It might be half a message. It might be one and a half messages. What it is is entirely up to you.
Use ZeroMQ if you're doing individual messages. It has bindings for a huge number of languages and is a great abstraction for networking. In fact, it can handle this proxy model for you.

can one call of recv() receive data from 2 consecutive send() calls?

i have a client which sends data to a server with 2 consecutive send calls:
send(_sockfd,msg,150,0);
send(_sockfd,msg,150,0);
and the server is receiving when the first send call was sent (let's say i'm using select):
recv(_sockfd,buf,700,0);
note that the buffer i'm receiving is much bigger.
my question is: is there any chance that buf will contain both msgs? of do i need 2 recv() calls to get both msgs?
thank you!
TCP is a stream oriented protocol. Not message / record / chunk oriented. That is, all that is guaranteed is that if you send a stream, the bytes will get to the other side in the order you sent them. There is no provision made by RFC 793 or any other document about the number of segments / packets involved.
This is in stark contrast with UDP. As #R.. correctly said, in UDP an entire message is sent in one operation (notice the change in terminology: message). Try to send a giant message (several times larger than the MTU) with TCP ? It's okay, it will split it for you.
When running on local networks or on localhost you will certainly notice that (generally) one send == one recv. Don't assume that. There are factors that change it dramatically. Among these
Nagle
Underlying MTU
Memory usage (possibly)
Timers
Many others
Of course, not having a correspondence between an a send and a recv is a nuisance and you can't rely on UDP. That is one of the reasons for SCTP. SCTP is a really really interesting protocol and it is message-oriented.
Back to TCP, this is a common nuisance. An equally common solution is this:
Establish that all packets begin with a fixed-length sequence (say 32 bytes)
These 32 bytes contain (possibly among other things) the size of the message that follows
When you read any amount of data from the socket, add the data to a buffer specific for that connection. When 32 bytes are reached, read the length you still need to read until you get the message.
It is really important to notice how there are really no messages on the wire, only bytes. Once you understand it you will have made a giant leap towards writing network applications.
The answer depends on the socket type, but in general, yes it's possible. For TCP it's the norm. For UDP I believe it cannot happen, but I'm not an expert on network protocols/programming.
Yes, it can and often does. There is no way of matching up sends and receive calls when using TCP/IP. Your program logic should test the return values of both send and recv calls in a loop, which terminates when everything has been sent or recieved.

Resources