Socket.Receive正在丢弃每个数据包的最后一个字节

时间:2010-11-11 20:34:00

标签: vb.net sockets

我在使用Visual Studio 2005在vb.net中编写的套接字客户端应用程序时遇到问题。客户端连接到在OpenVMS上运行的C语言套接字服务器。我遇到的问题是,当服务器发送数据包时,客户端不会收到(每个数据包的最后一个字节!)。我可以在网络上转储数据包,数据就在那里。我目前的解决方案是保持我的套接字消息短(247字节)并在我的数据末尾发送一个额外的字节。

我想在我的消息中包含更多信息,但我无法找到使其工作的方法。如果我知道100%的数据包将在网络上存在多长时间,我可以通过在正确的位置包含一个额外的字节来解决这个问题。但是,我不想对数据包的长度做任何假设。

有没有人对这个问题的最佳解决方案有任何建议?

以下是我的客户接收代码示例:

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

    Try
        nNumBytes = -1
        While (nNumBytes <> 0)

            nTotalBytes = 0
            RecvBuffer.Initialize()

            nNumBytes = ClientSocket.Receive(RecvBuffer, nTotalBytes, 4, SocketFlags.None)
            If nNumBytes > 3 Then
                SyncLock ClientSocket
                    AppendText("")
                    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), _
                                                        SocketFlags.None)
                        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
                            Number(ind) = System.Text.Encoding.ASCII.GetString(RecvBuffer, 5 + (ind * 12), 12)
                        Next

                        RefreshScreen()

                    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)
        Me.Invoke(cb)
        Return
    End Try

2 个答案:

答案 0 :(得分:1)

此问题已得到纠正。 TCP / IP服务器使用WRITE函数修饰符,最终设置TCP / IP数据包中的URG位。我认为服务器损坏了这个,不同的Windows客户端在处理这些数据包时遇到了各种各样的问题。

答案 1 :(得分:0)

实际上,发送额外字节并不能解决问题。只要我将套接字消息保持在大约247字节以下,它就会在一个数据包中发送。因此,发送一个额外的字节只能确保客户端接收到所有数据。

如果我发送更长的消息,那么根据消息的长度,每个数据包的末尾会丢失一个字节。这意味着如果我发送更长的消息,我将不得不通过假设它总是相同或者通过包含某种标记来帮助我找到消息中数据的偏移量来进行调整。

我认为应该有更好的解决方案。