Unix Network Programming Manual
Prev Page Next Page

Sending and Receiving




The actual passing of data is done in a manner similar to reading and writing a file. There are some differences between stream and datagram sockets, so stream sockets will be discussed here.

For example, to send data to the other end of a connection, use:

The return value is the number of bytes actually sent or -1 if an error occurs. sock is the socket, buf is the buffer of bytes to send and len is the length of buf in bytes. flags allows certain special operations to take place and they will be discussed later. If no special flags are needed, pass the flags value as zero.

There is no special format for buf - it is simply a string of bytes. However, it is not uncommon for there to be an overlying logical format that makes sense to the sender and (hopefully) the receiver. For example, msg could be a string of characters representing a sentence of English text, or it could be a set of binary integer values moved into msg. The format depends on the higher level protocol defined by the client-server protocol. For example:

sends 50 two-byte short integers to the socket. This is not the best way to do this, as will be pointed out later.

To receive data, use a call of the form: Everything is the same as in the send call, except that count is the number of bytes received from the connection. The len parameter indicates the maximum length of data that can be returned, so the number of bytes returned in msg will be len or less. It is not necessary to know exactly how many bytes are incoming.

recv is normally a blocking call, which means it waits until data is available before returning. If the other end of your connection does not send anything, your program will wait forever. One exception to this is if the other end has closed the connection. In the case of AF_UNIX communication, the recv will return zero indicating an end-of-file. However, communication between different machines will not provide this service. This is one of the reasons that communication protocols often include timers to interrupt receives that wait too long. There are a number of more sophisticated ways to handle incoming data, such as using interrupt-driven I/O and non-blocking receives. These advanced topics will be discussed later.

Stream communications can be tricky for beginners because it typically ignores boundaries (there are lots of different implementations of these methods, so nothing is absolute). That means that if you were to send two messages to the other end of a connection, it might receive them all in one piece, in two different pieces, or in more than two pieces. For example, if the sender executed (Note that the null character at the end of the string is not included in the message):
and the receiver executed:
The receiver might get "Message 1Message 2", or "Message 1Mess" or "Mess". For a stream connection, the operating system determines how much is sent and at what intervals. This can be an inconvenience at times, but has other properties that make it acceptable.
Prev Page Next Page