ManuelSchneid3r
ManuelSchneid3r

Reputation: 16121

Network programming. Determine end of message

Linux buffers all received messages received on a socket. But before receiving, this messages had a beginning and an end. Linux writes this messages sequentially in the buffer, loosing therefore the information of the end of the message.

I know that in Linux I could use cmsg_header.But Windows does not offer send-/recvmsg() procedures. How do I determine the end of a message on the buffer platformagnostic?

Upvotes: 2

Views: 1764

Answers (5)

bobah
bobah

Reputation: 18864

A network facing application typically has a clear transport/business logic separation.

Business layer operates whole messages only. Transport is delivering whole messages to the upstream business layer potentially assembling continuous stream from fragments, re-slicing, and re-interpreting it as a series of messages.

Transport layer is typically communicating with the remote transport layer using protocol messages of form [size(length=S)][payload(variable length)]. Where [size] is a single number whose marshalled length S is known to all communicating parties.

The first thing the transport layer does is it waits to receive S bytes from the downstream (either asynchronously or synchronously, does not matter) into a temporary buffer. Once done it unmarshals received data and becomes aware of the length of the payload to be received L.

Once the lenght of the payload L is known transport is waiting to receive L bytes from the downstream into a temporary buffer (may have to combine multiple reads) and once done it notifies application layer passing it the whole assembled message in a single buffer.

Upvotes: 1

user207421
user207421

Reputation: 311052

Linux writes this messages sequentially in the buffer, loosing therefore the information of the end of the message.

That's not correct. There was never any 'information [about] the end of the message' to lose at the receiving end. TCP is a byte-stream protocol. Your send()s or write()s got concatenated at the sender, into its socket send buffer, and from there the data was transmitted in TCP segments and IP packets however the transport decided to do so.

If you want messages over TCP, you have to implement them entirely yourself. Common techniques:

  • send a length word ahead of the message
  • encapsulate the message, e.g. between STX and ETX, with suitable escaping for ETX (ESC ETX) if it occurs in the message, and therefore with escaping for ESC itself (ESC ESC) when occurring in the message
  • use a self-describing protocol such as XML.

Upvotes: 2

Martin R
Martin R

Reputation: 540145

I think the Winsock equivalents of sendmsg, recvmsg are WSASendMsg and WSARecvMsg. They take a LPWSAMSG argument which is, according to the documentation, a structure based on the Posix.1g specification for the msghdr structure.

Upvotes: 2

Ed Heal
Ed Heal

Reputation: 60047

Just send in the first 4 bytes the length of the message in network order. Then you will not have this problem.

Upvotes: 5

I am not sure that TCP/IP connections are exchanging well delimited messages. Routers could fragment packets. (So cmsg_header could be unreliable).

All TCP/IP based protocols I know about (HTTP, SMTP, X11, RPCXDR) are handling message organization at the application level. Your application library need to know somehow when and when a "message" starts or ends.

Upvotes: 6

Related Questions