我创建了简单的tcp服务器 - 它工作得很好。
问题在我们切换到压力测试时开始 - 因为我们的服务器应该处理许多并发的开放套接字 - 我们已经创建了一个压力测试来检查它。 不幸的是,当并发打开套接字的数量大约为100时,服务器看起来像是窒息而且无法及时响应新的连接请求。
我们已经尝试过几种类型的服务器 - 并且都产生相同的行为。
服务器:可以像这篇文章中的样本(都产生相同的行为)
How to write a scalable Tcp/Ip based server
这是我们正在使用的代码 - 当客户端连接时 - 服务器将挂起以保持套接字处于活动状态。
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();
}
}
}
有一种简单的方法来解释这种行为吗?如果TCP服务器会产生更好的结果,可能是c ++实现?也许它实际上是客户端问题?
欢迎任何评论!
奥弗
答案 0 :(得分:0)
指定一个巨大的侦听器待办事项:http://msdn.microsoft.com/en-us/library/5kh8wf6s.aspx
答案 1 :(得分:0)
首先,每个连接设计的线程不太可能具有特别的可扩展性,您最好将设计基于使用IO完成端口的异步服务器模型。然而,在这种情况下,这不太可能是问题,因为你并没有真正强调服务器那么多。
其次,收听积压在这里是一个红鲱鱼。 listen backlog用于为等待接受的连接提供队列。在此示例中,您的客户端使用同步连接调用,这意味着客户端在任何时候都不会有超过1次未完成的连接尝试。如果您在客户端中使用异步连接尝试,那么您可能会考虑调整侦听backlog。
第三,假设客户端代码没有显示它发送任何数据,您可以简单地发出读取调用并删除其后的睡眠,读取调用将阻止。睡眠只是让人感到困惑。
您是否在同一台计算机上运行客户端和服务器?
这是客户端和服务器中的所有代码吗?
您可以尝试使用我在这里提供的免费TCP测试客户端从问题空间中消除客户端:http://www.lenholgate.com/blog/2005/11/windows-tcpip-server-performance.html
同样,您可以针对我的一个简单免费服务器测试您的测试客户端,例如:http://www.lenholgate.com/blog/2005/11/simple-echo-servers.html
我看不出任何明显错误的代码(除了整体设计)。