Begin-EndReceive看不到到达的数据

时间:2014-11-12 16:15:55

标签: c# sockets tcp mono wireshark

我的TCP客户端在接收数据时卡住了。

  1. 已建立连接
  2. 客户端发送21个字节。 (见#5)
  3. 下一个BeginReceive调用客户端永远不会调用回调。当我强制它调用EndReceive时,它会永远挂起。 IsCompleted = false。
  4. 有些数据在#5之后到达,但问题是它永远不会进入我的应用程序。 TcpClient.Available返回135。

    客户端可以发送数据,但它不会从服务器接收任何内容。

    wireshark window

    客户端使用Mono 2.6在Unity3D中运行。我只能在Unity Editor中首次启动才能重现它。第二次它开始很好但随机卡住(在编辑之外)。

    那么,为什么会这样呢?

    Wireshark log(设置过滤器tcp.port == 21050)。

    更新:另一个例子

    NoDelay = true,Blocking = false,LingerState.Enabled = false,Linger = 0

    发送操作使用Socket.Send,接收操作使用Socket.Begin-End-Receive

    服务器日志:

    500: Server started
    7832: 1: Next receive scheduling for time 25
    7863: 1: BeginReceive, available: 0
    7925: 1: About to process received data: 21
    7925: 1: Processing received data 21 // hello
    7941: 1: Send 4  // handshake
    7972: 1: Send 8  // init data
    8050: 1: Send 41 // init data
    8050: 1: Processing received data finished
    8050: 1: Next receive scheduling for time 0
    8050: 1: BeginReceive, available: 0
    8237: 1: Send 86 // init data
    8331: 1: About to process received data: 45
    8331: 1: Processing received data 45 // set position (x,y,z)
    8346: 1: Processing received data finished
    8346: 1: Next receive scheduling for time 0
    8346: 1: BeginReceive, available: 0
    9906: 1: About to process received data: 2
    9906: 1: Processing received data 2 // ping
    9906: 1: Send 4 // ping response, never reaches client
    9906: 1: Processing received data finished
    9906: 1: Next receive scheduling for time 0
    9906: 1: BeginReceive, available: 0
    

    客户日志:

    1: BeginReceive, available: 0
    1: Send 21 // hello
    1: EndReceive, available 0
    1: About to process received data: 4
    1: Processing received data 4 // handshake
    1: Processing received data finished
    1: Next receive scheduling for time 0
    1: BeginReceive, available: 135
    1: EndReceive, available 0
    1: About to process received data: 135 // 8 + 41 + 86
    1: Processing received data 135 // init data
    1: Processing received data finished
    1: Next receive scheduling for time 0
    1: Send 45 // set position (x,y,z)
    1: BeginReceive, available: 0
    1: Send 2  // ping
    
    Waiting ping result too long
    No receive for long time, force finish, completed: False
    
    1: EndReceive, available 0 // blocks forever
    

    Wireshark显示4个数据包已到达。如果服务器继续发送数据包,则它们将在客户端套接字上排队(可用> 0)。

1 个答案:

答案 0 :(得分:1)

似乎单声道的bug与mono不支持像MS .NET一样使用异步API的非阻塞套接字这一事实有关。由于性能原因,我需要使用非阻塞模式进行发送操作。我用SendAsync和BeginReceive替换了非阻塞Send和ReceiveAsync,现在已经修复了。通过一些努力,我使SendAsync的工作速度与非阻塞Send一样快。