〜1秒TcpListener Pending()/ AcceptTcpClient()滞后

时间:2010-04-29 20:46:00

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

可能只是观看此视频: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开销,我已经尝试在同一个线程中运行所有内容等等。

4 个答案:

答案 0 :(得分:3)

你应该考虑异步接受你的客户,这很可能会消除你所看到的滞后。

我稍微修改了你的代码

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);    
}

答案 1 :(得分:2)

也许这是某种dns解决方案?您是使用IP地址访问服务器的主机还是DNS正在解析的某个名称?除非客户端/网络端出现问题,否则ParmesanCodice提供的代码应该没有延迟。

尝试将以下行添加到windows \ system32 \ drivers \ etc \ hosts:

127.0.0.1       localhost

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

答案 2 :(得分:0)

调试器不会增加开销吗?

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

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

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

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

答案 3 :(得分:0)

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