Operating System - OpenVMS
Showing results for 
Search instead for 
Did you mean: 

Windows socket client drops the last byte of every packet

Frequent Advisor

Windows socket client drops the last byte of every packet

I am having trouble with a socket client application written in vb.net using Visual Studio 2005. The client connects to a C language socket server that is running on OpenVMS. The problem that I have is that when the server sends a packet, the client does not receive the last byte (of every packet!). I can dump the packets on the network and the data is all there. My current solution is to keep my socket messages short (247 bytes) and send one extra byte past the end of my data.

I would like to include more information in my messages and I cannot find a way to make this work. If I knew 100% how long the packets will be on the network, I could work around this by including an extra byte in just the right places. However, I don't want to make any assumptions about the length of the packets.

Does anyone have any suggestions about what the best solution is to this problem?
Joseph Huber_1
Honored Contributor

Re: Windows socket client drops the last byte of every packet

How does the client know the length of one message or record ? (I would not call it 'packet', since this is the unit the low level TCP/IP layers are exchanging the data).

Can You show us the loop done on the receiver(select,recv,read)?

Basically there two ways for a protocol:
(1) the protocol is 'binary': each message starts with a byte (or word-)count, and the receiver reads until the counted bytes are read.
(2) the protocol is (ascii-)text based: then usually the receiver reads until a terminator sequence (usually or ) received.

Frequent Advisor

Re: Windows socket client drops the last byte of every packet

Below is a copy of my code. After revisiting this, I am thinking that maybe, the problem is the offset which is the 2nd argument to ClientSocket.Recieve. I probably need to look at this a little closer.

Private Sub ReceiveMsg()
Dim nTotalBytes As Integer
Dim nNumBytes As Integer
Dim nMsgType As Short
Dim nMsgLen As Short
Dim ind As Integer

nNumBytes = -1
While (nNumBytes <> 0)

nTotalBytes = 0

nNumBytes = ClientSocket.Receive(RecvBuffer, nTotalBytes, 4, SocketFlags.None)
If nNumBytes > 3 Then
SyncLock ClientSocket
AppendText("Message Received " & Str(nNumBytes) & " Bytes")
nTotalBytes = nTotalBytes + nNumBytes
nMsgType = BitConverter.ToInt16(RecvBuffer, 0)
nMsgLen = BitConverter.ToInt16(RecvBuffer, 2)
If nMsgLen > 8191 Then
AppendText(" Error - Message length invalid: " & Str(nMsgLen))
nMsgLen = 250
End If

While (nTotalBytes < nMsgLen And nNumBytes > 0)
nNumBytes = ClientSocket.Receive(RecvBuffer, nTotalBytes, (nMsgLen - nTotalBytes), _
AppendText("Message Received " & Str(nNumBytes) & " Bytes")
nTotalBytes = nTotalBytes + nNumBytes
End While
End SyncLock

AppendText("Total Bytes Received = " & Str(nTotalBytes))
AppendText("MsgLen from Message = " & Str(nMsgLen))
Select Case nMsgType
Case 1
AppendText(" Liftpos = " & System.Text.Encoding.ASCII.GetString(RecvBuffer, 4, 1))

For ind = 0 To NUM_LOCATIONS - 1
SlabNo(ind) = System.Text.Encoding.ASCII.GetString(RecvBuffer, 5 + (ind * 12), 12)


Case Else
AppendText(" Unrecognized message type: " & Str(nMsgType))

End Select

End If
End While

Catch ex As Exception
' Tell the main thread to invoke DisconnectedUI
Dim cb As New SimpleCallback(AddressOf DisconnectedUI)
End Try
Honored Contributor

Re: Windows socket client drops the last byte of every packet

You are aware that there are no packets with TCP, and that your code is entirely responsible for waiting for the characters to arrive from the stream, and for building up and chunking up the "packets" from one or more I/O calls before using the contents of the "packet"?

Now UDP? UDP has packets; one message, one datagram. You either get the message, or you don't. If you don't, you resend.

If this isn't the usual case of processing a stream into packets (and a late-arriving byte), and your code is doing assembly and disassembly as the data arrives, then your code probably has a bug. The numbers of different ways this can go off the rails is large; C and BASIC differ in how they index stuff, and C is quite fond of off-by-one bugs, or any number of other bug-like creatures in the respective critter zoos of C and BASIC.

It's also possible the underlying code has a bug, though any bugs lurking in an IP stack transport tend to show up all over the place; all sorts of stuff breaks.

I'll also mention that the underlying problems here have long been solved, as have most of the related problems of recovery and restarts and related. Writing socket code was commonplace a quarter century ago (and many of us suffered through the "fun" of debugging that stuff), but there are now good libraries and transports that can deal with this dreck. Even on VMS. I'd suggest looking at zeroMQ (0MQ) as a starting point, though there are various other options.
Frequent Advisor

Re: Windows socket client drops the last byte of every packet

Thanks for your comments. I think I have a program bug.
Frequent Advisor

Re: Windows socket client drops the last byte of every packet

OK, It has been a while since I abandoned this, so I have spent some time running with the debugger to review what is happening:

1) VMS socket server sends a QIOW with the message length (400) encoded in the message. However, the length specified on the QIOW is 402.

2) Windows vb.Net client receives 4 bytes from the stream to get the msg type and msg length. It sees that the msg length is 400

3) Windows vb.Net client calculates the size of the rest of the message (400 - 4 = 396) and then receives 396 bytes.

4) The data received is missing two bytes of the data that was sent, but is happy because it thinks it is only supposed to receive 400 bytes instead of 402. It then waits for more data.

By Using TCPTRACE on OpenVMS, I see the stream of bytes split into two packets. The missing bytes are the last byte included in each packet. All of the data can be viewed in TCPTRACE, but the vb.Net client does not receive it. FYI the code pasted above is slightly different than the code I am currently using to try to test longer messages, but it operates the same way. (Meaning that I send 248 bytes with an encoded msg length of 247. I only add one extra byte, because the client only drops one byte due to the entire message being sent in a single packet.)

My client receives multiple messages that are identical with the exact same results every time.

If someone wants to see the details, I can send the current client code and the TCPTRACE output.