【问题标题】:Linux Overlapped I/O TCP socket server not responsing to C# ASync Client correctlyLinux 重叠 I/O TCP 套接字服务器未正确响应 C# ASync 客户端
【发布时间】:2015-04-19 13:41:26
【问题描述】:

我正在尝试编写一个简单的功能回显套接字客户端/服务器。我已经设法让一个带有客户端的同步服务器工作,但现在我需要一个异步的。

如果我使用 Microsoft 的版本,它运行良好,异步 服务器

https://msdn.microsoft.com/en-us/library/fx6588te(v=vs.110).aspx

Microsoft ASync 客户端

https://msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx

我现在正在尝试让 Microsoft Async ClientLinux C++ Overlapped I/O Server 进行通信:

http://www.tutorialized.com/tutorial/Linux-C-Overlapped-Server-and-Client-Socket-Example/77220

问题从这里开始。连接已建立,我可以向服务器发送消息,服务器响应回显消息(根据调试和终端输出),但 Microsoft ASync 客户端从未在其套接字上获得响应。

是否无法将异步客户端连接到重叠 I/O 服务器?我不确定为什么来自服务器的回复永远不会到达客户端。调试 Microsoft ASync 客户端告诉我 Receive 函数永远不会通过这行代码:

receiveDone.WaitOne();

receiveDone 是一个 ManualResetEvent:

private static ManualResetEvent receiveDone =
            new ManualResetEvent(false);

上下文:

// Receive the response from the remote device.
Receive(client);
receiveDone.WaitOne();

这里是接收的回调函数,完成后设置receiveDone。 bytesRead 永远不会超过 0。:

private void ReceiveCallback(IAsyncResult ar)
{
    try
    {
        // Retrieve the state object and the client socket 
        // from the asynchronous state object.
        StateObject state = (StateObject)ar.AsyncState;
        Socket client = state.workSocket;

        // Read data from the remote device.
        int bytesRead = client.EndReceive(ar);

        if (bytesRead > 0)
        {
            // There might be more data, so store the data received so far.
            state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

            // Get the rest of the data.
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReceiveCallback), state);
        }
        else
        {
            // All the data has arrived; put it in response.
            if (state.sb.Length > 1)
            {
                response = state.sb.ToString();
            }
            // Signal that all bytes have been received.
            receiveDone.Set();
        }
    }
    catch (Exception e)
    {
        msg("Fail ReceiveCallback: " + e.Message, false);
    }
} 

无论如何,此代码在连接到异步服务器时有效,但不是重叠 I/O 服务器,所以实际上我要求在 Overlapped I/O server code 中更改什么,以便它发送回异步客户端的消息能收到吗?

如果从异步客户端发送Hello World,这是服务器的输出:

root@deb7sve:/home/petlar/Host/SockServer# g++ OverlappedServer.cpp -o os.out -lpthread
root@deb7sve:/home/petlar/Host/SockServer# ./os.out
---------------------
Received connection from 10.0.2.2
Read 13 bytes from 4
Sent 13 bytes to 4

【问题讨论】:

  • 这段代码不是异步的,因为可能有一个线程正在等待事件。这是毫无意义的 MSDN 示例代码。你得到可怕的异步代码,却得不到任何好处。
  • 服务器发送完成后是否关闭连接?
  • 我不确定微软的例子是否是好的异步例子,但我会在稍后与服务器建立简单的通信时尝试改进客户端。不,服务器等待更多数据包,并将它们回显给客户端。代码没看错的话最多100个客户端,但是示例代码缺少对socket等的清理和重用,所以很简单。

标签: c# linux sockets asynchronous overlapped-io


【解决方案1】:

该客户端代码仅在连接关闭时设置事件。根据您的评论,服务器不会关闭连接。这就是为什么永远不会设置事件的原因。

丢弃客户端代码并使用简单的同步代码重写它。 50% 的代码用于制作异步 IO(以损坏的方式)。异步 IO 不是为了提高网络效率。它的存在是为了节省线程资源。客户端可能不需要它。

【讨论】:

  • 从来没有想过客户端正在等待连接的关闭。我会考虑的,谢谢!
  • 太好了,成功了!一旦我在回显响应后测试关闭套接字服务器端,回显消息就会出现在客户端上。好的,我现在明白了,客户端代码需要刷一下,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-12
  • 1970-01-01
  • 2016-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多