~ 1 секунда TcpListener Pending () / AcceptTcpClient () задержка - PullRequest
3 голосов
/ 30 апреля 2010

Возможно, просто посмотрите это видео: 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 ]

3 голосов
/ 30 апреля 2010

Вы должны принять асинхронный прием своих клиентов, это, скорее всего, устранит наблюдаемую задержку.

Я немного изменил ваш код

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);    
}
2 голосов
/ 04 мая 2010

Может это какой нибудь днс разрешить? Используете ли вы IP-адрес для доступа к хосту вашего сервера или какое-либо имя, которое разрешается вашим DNS? Код, который ParmesanCodice дал, должен работать без задержки, если что-то не так на стороне клиента / сети.

Попробуйте добавить следующую строку в ваши windows \ system32 \ drivers \ etc \ hosts:

127.0.0.1       localhost

это может решить вашу проблему или просто подключиться как 127.0.0.1:85

0 голосов
/ 29 сентября 2011

Вы можете избежать всего цикла Listener.Pending while.AcceptTcpClient () является блокирующим вызовом, так что вы можете просто позволить своему коду работать и ожидать его.Я не знаю, почему этот цикл занял бы 1 секунду (вместо 1 миллисекунды), но, поскольку вы указываете, что именно там находится задержка, вы можете избавиться от нее.

0 голосов
/ 19 мая 2010

Разве отладчик не добавляет накладных расходов?

У меня были такие проблемы, когда я собирал свой сервер MMO. не могу вспомнить, как я обошел это сейчас.

Я думаю, что это как-то связано с распределением ресурсов на сервисах, я использую подход, предложенный ParmesanCodice (по крайней мере, похожий), и во время тестирования я обнаружил, что первые 5-10 соединений были мусором, но после этого сервис кажется, выбивают новые связи, как будто завтра не будет ...

Может быть, это вещь сокета в рамках.

Вы пробовали нагрузочный тест? Бросьте на него 1000 соединений и посмотрите, что произойдет, оно должно стать быстрее после обработки каждого из них.

...