【问题标题】:Socket.Receive is dropping the last byte of every packetSocket.Receive 正在丢弃每个数据包的最后一个字节
【发布时间】:2010-11-11 20:33:59
【问题描述】:

我在使用 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

【问题讨论】:

  • 我看不出有什么问题。非常神秘的是you 是如何通过发送一个额外的字节来解决这个问题的。您说 server 消息缺少一个字节。

标签: vb.net sockets


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2014-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-02
      • 1970-01-01
      • 2022-08-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多