Search code examples
c#.netsocketstcpstx

Sending/Receiving messages framed for serial communication over .Net Socket


We have done some basic TCP communication, but have a few questions. We are communicating with a TCP server where the transaction flow is described as follows:

The sender initiates the transaction by sending an STX (ASCII 0x02) character, then waits for the recipient to reply by sending an ACK (ASCII 0x06) character. After an ACK is received, the sender transmits a four-byte, unsigned, big-endian integer representing the size of the message payload, followed by the payload, and finally a 16-byte MD5 message digest for the payload. If the recipient is satisfied with the message, it sends an ACK character.

<STX> = ASCII 0x02
<ACK> = ASCII 0x06

Sender: <STX>     <0x00><0x00><0x00><0x05><'H'><'E'><'L'><'L'><'O'><0xEB><0x61>...
Recipient:   <ACK>                                                                <ACK>

Using .Net sockets (System.Net.Sockets.Socket), what is the proper way to manage the STX/ACK transfer control? Does the socket handle this automatically (i.e. Do we simply call socket.Send(byteData)), or do we need to explicitly send the STX, wait for ACK, etc.?

The same goes for receiving: Do we simply receive the incoming data, or do we need to listen for an STX character, send an ACK, prepare for the payload, etc.?

If the transfer control is handled automatically, are there any specific socket flags that we need to set?

FYI: We found several links (like the following) that have proved useful for message framing, but none discuss the STX/ACK transfer control:


Solution

  • Hehe, this used to be a serial port protocol, they probably just moved it unchanged to use sockets instead. Not that uncommon, although it isn't very suitable for a stream like TCP implements.

    Well, follow the instructions. Assuming you are the client, read one byte and verify its is 0x02. If it is, send back one byte, 0x06. If not, keep reading until you see the 0x02. You're now 'connected', but you already knew that.

    Next, read 4 bytes so you know the packet length, read as many bytes + 2 to get the rest of the packet. I'd ignore the 'MD5 digest', TCP is reliable enough to not have to double-check the validity of the received data. Send back one byte, 0x06.

    The only thing that isn't clear is whether you should expect a 0x02 before the packet length or not. The text says you don't, the diagram says you do.