간단한 tcp 서버를 만들었습니다.간단한 TCP 서버 스트레스 테스트시 10060 (Connection Timed Out)이 발생 함
스트레스 테스트로 전환하면 문제가 발생합니다. 우리 서버가 많은 동시 오픈 소켓을 처리해야하기 때문에이를 확인하기 위해 스트레스 테스트를 만들었습니다. 동시 오픈 소켓 수가 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++ 구현일까요? 어쩌면 실제로 클라이언트 측 문제일까요?
모든 의견을 환영합니다!
오퍼
테스트 할 OS는 무엇입니까? 모든 연결에 대해 새 스레드를 만들지 않아야합니다. 일반적인 확장 성을 위해 비동기 인터페이스를 사용해야합니다. BeginAccept, BeginReceive 등을 참조하십시오. –
win 7. 비동기 접근 방식이 바람직하다는 사실을 알고 있습니다. 그러나 위에서 설명한 동작은 시도한 모든 서버 구현에서 발생합니다 (콜백 포함). – ofer
클라이언트 당 하나의 스레드를 시작하면 안됩니다. 이것은 실제 작업을 수행하는 것보다 프로세스가 스케줄링에 더 많은 시간을 소비하므로 잘 확장되지 않습니다. 스레드 풀을 대신 사용하십시오. 일단 사용되면 스트림도 닫아야합니다 (C# 패턴을보십시오). –