Reputation: 16121
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
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
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:
Upvotes: 2
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
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
Reputation: 1
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