Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 压力测试简单tcp服务器时获得10060(连接超时)_C#_.net_Sockets_Winsock_Winsock2 - Fatal编程技术网

C# 压力测试简单tcp服务器时获得10060(连接超时)

C# 压力测试简单tcp服务器时获得10060(连接超时),c#,.net,sockets,winsock,winsock2,C#,.net,Sockets,Winsock,Winsock2,我创建了一个简单的tcp服务器,它工作得很好 当我们切换到压力测试时,问题就开始了——因为我们的服务器应该处理许多并发的开放套接字——我们创建了一个压力测试来检查这一点。 不幸的是,当并发开放套接字的数量在100个左右时,服务器似乎阻塞了,无法及时响应新的连接请求 我们已经尝试了几种类型的服务器,并且都产生了相同的行为 服务器:可以类似于本文中的示例(都产生相同的行为) 下面是我们正在使用的代码—当客户端连接时—服务器将挂起以保持套接字活动 enter code here 公共类服务器 {

我创建了一个简单的tcp服务器,它工作得很好

当我们切换到压力测试时,问题就开始了——因为我们的服务器应该处理许多并发的开放套接字——我们创建了一个压力测试来检查这一点。 不幸的是,当并发开放套接字的数量在100个左右时,服务器似乎阻塞了,无法及时响应新的连接请求

我们已经尝试了几种类型的服务器,并且都产生了相同的行为

服务器:可以类似于本文中的示例(都产生相同的行为)

下面是我们正在使用的代码—当客户端连接时—服务器将挂起以保持套接字活动

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客户端,它一个接一个地循环和打开sokets

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




        }
    }
}
类程序
{
静态列表套接字;
静态私有void go(){
Socket newsock=新套接字(AddressFamily.InterNetwork,
流,ProtocolType.Tcp);
IPEndPoint iep=新IPEndPoint(IPAddress.Parse(“11.11.11.11”),2060);
尝试
{
NewStock.Connect(iep);
}
捕获(SocketException例外)
{
控制台写入线(例如消息);
}
锁(插座)
{
sockets.Add(newsock);
}
}
静态void Main(字符串[]参数)
{
套接字=新列表();
//int start=1;//Int32.Parse(Console.ReadLine());
对于(int i=1;i<1000;i++)
{   
go();
睡眠(200);
}
控制台。写线(“按键”);
Console.ReadKey();
}
}
}
有没有简单的方法来解释这种行为?如果TCP服务器能产生更好的结果,也许C++实现?也许这实际上是客户端的问题

欢迎任何评论


ofer

指定一个巨大的侦听器积压:

首先,每个连接的线程设计不太可能具有特别的可伸缩性,您最好将设计基于异步服务器模型,该模型在引擎盖下使用IO完成端口。但是,在这种情况下,这不太可能是问题所在,因为您并没有对服务器施加太大的压力

其次,在这里,倾听积压是一个危险的话题。侦听积压用于为等待接受的连接提供队列。在本例中,客户端使用同步连接调用,这意味着客户端在任何时候都不会有超过1次未完成的连接尝试。如果您在客户机中使用异步连接尝试,那么您可以考虑调优listen backlog

第三,如果客户机代码没有显示它发送了任何数据,您可以简单地发出read调用并删除它之后的休眠,read调用将被阻塞。睡眠只是把事情弄糊涂了

您是否在同一台计算机上运行客户端和服务器

这是客户端和服务器中的全部代码吗

您可以尝试使用我的免费TCP测试客户端从问题空间中删除客户端,该客户端可在以下位置获得:

同样,您可以针对我的一个简单免费服务器测试您的测试客户机,如下所示:


我看不出代码有任何明显的错误(除了总体设计)。

您测试的是什么操作系统?您不应该为每个连接创建一个新线程,您应该考虑使用异步接口来实现一般的可伸缩性,请参见beginacept、BeginReceive等。我知道异步方法更可取。但是,上述行为发生在我尝试的任何服务器实现上,包括回调。您不应该为每个客户端启动一个线程。这不能很好地扩展,因为该过程将花费比实际工作更多的时间进行调度。改用线程池。您还应该在使用流之后关闭它们(查看C#using模式)。使用异步API。即使您的服务器不做任何其他事情(比如说,服务内容),您也将被限制在任何32位进程中。第二,请编辑您的问题,提供以下信息:操作系统(是的,这非常重要)和您收到的错误消息(以及您从哪里得到的)。我试着将backlog设置为Int32.MaxValue,但没有多大帮助,tcplistener也默认为Int32.MaxValue,这恰好是一个使用系统默认值的特殊常量,我猜大约是100(我想是128)。幸运吧?试试10000。(来源:)在这种情况下,你不应该需要一个“庞大”的监听积压。侦听积压用于确定正在建立的连接队列的大小。在这里,我们每200ms有一个连接,即使没有特别可扩展的线程连接,设计服务器应该能够比客户端启动连接更快地接受连接,特别是因为客户端发出阻塞连接调用,所以在连接完成之前,200ms计时器甚至不会启动。。。