【问题标题】:~1 second TcpListener Pending()/AcceptTcpClient() lag~1 秒 TcpListener Pending()/AcceptTcpClient() 滞后
【发布时间】:2011-09-29 13:48:44
【问题描述】:

可能只看这个视频:http://screencast.com/t/OWE1OWVkO 如您所见,启动连接(通过 telnet 或 firefox)与我的程序第一次得到消息之间的延迟。

这是等待连接的代码

    public IDLServer(System.Net.IPAddress addr,int port)
    {
        Listener = new TcpListener(addr, port);

        Listener.Server.NoDelay = true;//I added this just for testing, it has no impact

        Listener.Start();

        ConnectionThread = new Thread(ConnectionListener);
        ConnectionThread.Start();


    }

    private void ConnectionListener()
    {
        while (Running)
        {
            while (Listener.Pending() == false) { System.Threading.Thread.Sleep(1); }//this is the part with the lag
            Console.WriteLine("Client available");//from this point on everything runs perfectly fast 
            TcpClient cl = Listener.AcceptTcpClient(); 

            Thread proct = new Thread(new ParameterizedThreadStart(InstanceHandler));
            proct.Start(cl);


        }

    }

(我在将代码放入代码块时遇到了一些麻烦)

我尝试了几种不同的方法,难道我使用的是 TcpClient/Listener 而不是原始的 Socket 对象吗?我知道这不是强制性的 TCP 开销,我已经尝试在同一个线程中运行所有内容,等等。

【问题讨论】:

  • 你终于找到问题了吗?
  • 好奇你是怎么解决这个问题的,遇到同样的问题

标签: c# performance c#-3.0 sockets tcplistener


【解决方案1】:

也许是某种 dns 解析?您是否使用 IP 地址来访问您的服务器的主机或您的 DNS 正在解析的某个名称?除非客户端/网络端出现问题,否则 ParmesanCodice 提供的代码应该可以立即运行。

尝试在您的 windows\system32\drivers\etc\hosts 中添加以下行:

127.0.0.1       localhost

它可能会解决您的问题或只是连接为 127.0.0.1:85

【讨论】:

  • 我在连接中一直有 1 秒的延迟,即使是异步进行也是如此。这个答案为我解决了这个问题,它似乎有点愚蠢,但连接到 127.0.0.1 而不是 localhost 为我修复了它。我的猜测是问题出在某些防火墙/防病毒/securitycrepthingy
【解决方案2】:

您应该考虑异步接受您的客户,这很可能会消除您看到的延迟。

我稍微修改了你的代码

public IDLServer(System.Net.IPAddress addr,int port)
{
    Listener = new TcpListener(addr, port);

    Listener.Start();        

    // Use the BeginXXXX Pattern to accept clients asynchronously
    listener.BeginAcceptTcpClient(this.OnAcceptConnection,  listener);
}

private void OnAcceptConnection(IAsyncResult asyn) 
{
    // Get the listener that handles the client request.
    TcpListener listener = (TcpListener) asyn.AsyncState;

    // Get the newly connected TcpClient
    TcpClient client = listener.EndAcceptTcpClient(asyn);

    // Start the client work
    Thread proct = new Thread(new ParameterizedThreadStart(InstanceHandler));
    proct.Start(client);

    // Issue another connect, only do this if you want to handle multiple clients
    listener.BeginAcceptTcpClient(this.OnAcceptConnection,  listener);    
}

【讨论】:

  • 不,即使这样,延迟仍然会在调用 OnAcceptConnection 回调之前发生。
  • 这个例子无助于解决约 1 秒的延迟。 @hoodos 已经发布了正确答案。
【解决方案3】:

调试器不会增加开销吗?

我在构建 MMO 服务器时遇到了类似的问题。 不记得我现在是如何绕过它的。

我认为这与服务的资源分配有关,我使用 ParmesanCodice 建议的方法(至少类似的方法),在测试期间我发现前 5 到 10 个连接是垃圾,但之后服务似乎在敲出新的联系,就像没有明天一样......

也许它是框架中的一个套接字。

您是否尝试过负载测试? 向它抛出 1000 个连接,看看会发生什么,处理每个连接后它应该会变得更快。

【讨论】:

    【解决方案4】:

    您可以避免整个 Listener.Pending while 循环。 AcceptTcpClient() 是一个阻塞调用,因此您可以让您的代码运行并挂起。我不知道为什么那个循环需要 1 秒(而不是 1 毫秒),但既然你指出这是滞后的地方,你可以摆脱它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 1970-01-01
      • 2014-07-14
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 2020-08-25
      相关资源
      最近更新 更多