【问题标题】:C#5.0 asynchronous TCP/IP server with await & async带有等待和异步的 C#5.0 异步 TCP/IP 服务器
【发布时间】:2014-04-08 07:48:48
【问题描述】:

我已经写了以下 Tcp Server 应用程序。问题是它没有并行执行单个客户端。也就是说,如果连接了一个客户端,则服务器不接受与其他客户端的连接。请帮我修复代码:

void Run()
{
    tcpListener.Start();           

    while (true)
    {
        Console.WriteLine("Waiting for a connection...");

        try
        { 
            var client = await tcpListener.AcceptTcpClientAsync();
            await Accept(client);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

private async Task Accept(TcpClient client)
{
    //get client information 
    string clientEndPoint = GetClientIPAddress(client);            
    Console.WriteLine("Client connected at " + clientEndPoint);
    log.Info("Client connected at " + clientEndPoint);

    await Task.Yield (); 

    try 
    {              
        using (client) 
            using (NetworkStream stream = client.GetStream ()) 
            { 
                byte[] dataReceived = new byte [50];                  
                while (await stream.ReadAsync(dataReceived, 0, dataReceived.Length) != 0) //read input stream                
                {                    
                    //process data here                        
                    await ProcessData(dataReceived);                      
                }                   
            }
    } //end try
    catch (Exception ex) 
    {
        Console.WriteLine(ex.Message);                
        if (client.Connected)
            client.Close();
    }
} //end Accept(TcpClient client)

【问题讨论】:

  • 您是否尝试多次连接到同一个端口?

标签: c# asynchronous async-await


【解决方案1】:

问题是这样的:

await Accept(client);

您正在等待Accept 的结果,因此您无法接受新连接(因为您没有执行AcceptTcpClientAsyncAccept 处于“运行中”)。

这是一个如何正确完成的示例:https://stackoverflow.com/a/21018042/1768303

【讨论】:

  • 你应该把它改成async void Accept(client) {...},然后在Run方法中不带await关键字正常调用。
  • @Laith,我不是async void 即发即弃方法的忠实粉丝。我更喜欢跟踪待处理的任务,如链接的answer 中所做的那样。
  • 你是对的。如果你想跟踪所有正在运行的任务,你会想以某种方式保留对它们的引用。你的方法更好:)
  • 非常感谢!是的,将 await 从 Accept 调用中移开并将 Accept return 从 Task 更改为 void 确实解决了问题。
  • 实际上根据您的 cmets 我将任务添加回 Accept 并以这种方式调用它: var task = Accept(client)
猜你喜欢
  • 2010-10-22
  • 1970-01-01
  • 2012-10-14
  • 2017-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
相关资源
最近更新 更多