получение 10060 (тайм-аут соединения) при стресс-тестировании простого tcp-сервера - PullRequest
1 голос
/ 29 декабря 2010

Я создал простой tcp сервер - он работает довольно хорошо.

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

мы уже пробовали несколько типов серверов - и все они работают одинаково.

сервер: может быть что-то вроде примеров в этом посте (все выдают одинаковое поведение)

Как написать масштабируемый сервер на основе Tcp / Ip

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

enter code here

Сервер публичного класса

{
    private static readonly TcpListener listener = new TcpListener(IPAddress.Any, 2060);

    public Server()
    {
        listener.Start();
        Console.WriteLine("Started.");

        while (true)
        {
            Console.WriteLine("Waiting for connection...");
            var client = listener.AcceptTcpClient();
            Console.WriteLine("Connected!");
            // each connection has its own thread
            new Thread(ServeData).Start(client);
        }
    }

    private static void ServeData(object clientSocket)
    {
        Console.WriteLine("Started thread " + Thread.CurrentThread.ManagedThreadId);

        var rnd = new Random();
        try
        {
            var client = (TcpClient)clientSocket;
            var stream = client.GetStream();
            byte[] arr = new byte[1024];
            stream.Read(arr, 0, 1024);
            Thread.Sleep(int.MaxValue);

        }
        catch (SocketException e)
        {
            Console.WriteLine("Socket exception in thread {0}: {1}", Thread.CurrentThread.ManagedThreadId, e);
        }
    }
}

клиент стресс-теста: простой tcp-клиент, который зацикливает и открывает сокеты, один за другим

class Program
    {
        static List<Socket> sockets;
        static private void go(){
            Socket newsock = new Socket(AddressFamily.InterNetwork,
                                  SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint iep = new IPEndPoint(IPAddress.Parse("11.11.11.11"), 2060);
            try
            {
                newsock.Connect(iep);
            }
            catch (SocketException ex)
            {
                Console.WriteLine(ex.Message );
            }
            lock (sockets)
            {
                sockets.Add(newsock);
            }

        }
        static void Main(string[] args)
        {
            sockets = new List<Socket>();
            //int start = 1;// Int32.Parse(Console.ReadLine());
            for (int i = 1; i < 1000; i++)
            {   
                go();
                Thread.Sleep(200);
            }
            Console.WriteLine("press a key");
            Console.ReadKey();




        }
    }
}

Есть ли простой способ объяснить это поведение? Может быть, реализация C ++, если TCP-сервер будет давать лучшие результаты? может быть, это на самом деле проблема на стороне клиента?

Любой комментарий будет приветствоваться!

Офер

Ответы [ 2 ]

0 голосов
/ 29 декабря 2010

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

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

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

Работаете ли вы клиент и сервер на одной машине?

Это ВСЕ код и на клиенте, и на сервере?

Возможно, выпопробуйте удалить клиента из проблемного пространства с помощью моего бесплатного тестового клиента TCP, который доступен здесь: http://www.lenholgate.com/blog/2005/11/windows-tcpip-server-performance.html

Аналогично, вы можете протестировать свой тестовый клиент на одном из моих простых бесплатных серверов, например на этом:http://www.lenholgate.com/blog/2005/11/simple-echo-servers.html

Я не вижу ничего явно неправильного в коде (кроме общего дизайна).

0 голосов
/ 29 декабря 2010

Укажите огромное отставание слушателя: http://msdn.microsoft.com/en-us/library/5kh8wf6s.aspx

...