【问题标题】:VB.NET Asynchronous sockets packets getting lostVB.NET 异步套接字数据包丢失
【发布时间】:2011-10-15 21:26:03
【问题描述】:

我创建了一个可以同时与多个客户端通信的 TCP 服务器,但我似乎无法使它们稳定。当其中一个客户端向服务器发送 100 个数据包时,服务器只收到其中的一小部分。

Here's the client code in PasteBin。它显示了客户端如何连接到服务器,然后在 For 循环中向服务器发送 100 条消息。

And here's how the server handles the connection。我无法粘贴完整的源代码,因为它有数百行,所以如果它缺少任何强制性部分,请告诉我,我也会上传它们。

【问题讨论】:

    标签: .net vb.net sockets asynchronous packet-loss


    【解决方案1】:

    我也在 reddit 上回答了你的问题,但我想我会在这里回复,以防其他人正在搜索这种东西。

    服务器处理读取的方式存在两个问题。首先,你的客户端对象的构造函数:

    Public Sub New(ByVal client As TcpClient)
        'New client connects
        Me.client = client
        client.GetStream().BeginRead(New Byte() {0}, 0, 0, AddressOf Read, Nothing)
    End Sub
    

    BeginRead 期望您以可以传递给回调方法的方式收集数据;在这种情况下“阅读”。通常,这是通过创建一个新对象来保存此异步操作的“状态”并将其作为最后一个参数传递给 BeginRead 来完成的。您在此处的方法调用正在创建一个新的字节数组,但没有持有对它的引用以作为该方法的最后一个参数传入。这意味着通过此调用读取的数据将在读取后消失,因为它永远不会传递给存储它的方法。

    其次,您的读取操作:

    Public Sub Read(ByVal ar As IAsyncResult)
        Dim reader As New StreamReader(client.GetStream())
        clientPacket &= reader.ReadLine()
        client.GetStream().BeginRead(New Byte() {0}, 0, 0, AddressOf Read, Nothing)
    End Sub
    

    由于您没有传递在异步调用中读取的数据,因此您在此处创建了一个新的 StreamReader 以从客户端提取更多数据。这不是异步方法调用。您的 reader.ReadLine() 调用将阻塞,直到遇到换行符,此时数据将附加到 clientPacket。然后您再次调用 BeginRead,出现与上述相同的问题,这意味着您将丢失更多数据。

    此外,您永远不会通过在流上调用 EndRead() 来清除 AsyncResult 对象,当 CLR 用完异步操作的工作线程时,这最终会导致资源匮乏。

    这是我实现此类任务的方式的一个示例。它在 C# 中,因为这是我最满意的,对此我深表歉意。 ;)

    Client Code

    Server Code

    我希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2017-05-30
      • 1970-01-01
      • 2014-11-11
      • 1970-01-01
      • 2020-06-23
      • 2019-08-16
      • 2015-01-28
      • 2017-02-16
      • 2019-06-05
      相关资源
      最近更新 更多