2010-12-29 3 views
1

간단한 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++ 구현일까요? 어쩌면 실제로 클라이언트 측 문제일까요?

모든 의견을 환영합니다!

오퍼

+1

테스트 할 OS는 무엇입니까? 모든 연결에 대해 새 스레드를 만들지 않아야합니다. 일반적인 확장 성을 위해 비동기 인터페이스를 사용해야합니다. BeginAccept, BeginReceive 등을 참조하십시오. –

+0

win 7. 비동기 접근 방식이 바람직하다는 사실을 알고 있습니다. 그러나 위에서 설명한 동작은 시도한 모든 서버 구현에서 발생합니다 (콜백 포함). – ofer

+1

클라이언트 당 하나의 스레드를 시작하면 안됩니다. 이것은 실제 작업을 수행하는 것보다 프로세스가 스케줄링에 더 많은 시간을 소비하므로 잘 확장되지 않습니다. 스레드 풀을 대신 사용하십시오. 일단 사용되면 스트림도 닫아야합니다 (C# 패턴을보십시오). –

답변

0

거대한 리스너 백 로그를 지정 http://msdn.microsoft.com/en-us/library/5kh8wf6s.aspx

+0

. 나는 백 로그를 Int32.MaxValue로 설정하려고 시도했다. - 많이 도움이되지 않았다. – ofer

+0

예, tcplistener는 또한 기본값 인 int32.maxvalue를 기본값으로 사용하는데, 이는 시스템 상수를 사용하는 특수 상수가된다. 생각한다). 행운의 허? 10000을 시도하십시오. (출처 : http://msdn.microsoft.com/en-us/library/ms739168%28VS.85%29.aspx) – fejesjoco

+0

이 경우에는 '거대한'대기 백 로그가 필요하지 않습니다. 청취 백 로그는 설정중인 연결 큐의 크기를 지정하는 데 사용됩니다. 여기서 우리는 200ms 당 하나의 연결을 가지고 있습니다. 특히 연결 당 스레드가 특별히 확장 가능하지는 않지만 클라이언트가 연결 연결 호출을 발급하고 있으므로 200ms가 걸리므로 서버가 클라이언트가 연결을보다 빠르게 받아 들일 수 있어야합니다. 타이머는 연결이 완료 될 때까지 시작하지 않습니다. –

0

첫째로 연결 디자인 당 스레드, 당신은 IO 완료를 사용하는 비동기 서버 모델에 설계를 기반으로하는 것이 더 할 것, 특히 확장 될 가능성이 후드 아래의 항구. 그러나이 경우 서버에 그다지 많은 부담을주지 않으므로 문제가되지는 않습니다.

두 번째로 청취 백 로그는 여기에서 빨간색 청어입니다. 대기중인 백 로그는 허용 대기중인 연결에 대한 대기열을 제공하는 데 사용됩니다. 이 예에서 클라이언트는 동기 연결 호출을 사용합니다. 이는 클라이언트가 한 번에 두 개 이상의 연결 시도가 해결되지 않았 음을 의미합니다. 클라이언트에서 비동기 연결 시도를 사용했다면 아마 청취 백 로그를 조정하는 것이 좋을 것입니다.

세 번째로 클라이언트 코드에서 데이터를 전송하지 않는다는 것을 고려하면 읽기 호출을 실행하고 그 뒤에 오는 절전 모드를 제거하면 읽기 호출이 차단됩니다. 수면은 문제를 혼란스럽게합니다.

동일한 컴퓨터에서 클라이언트와 서버를 실행하고 있습니까?

이 코드가 클라이언트와 서버 모두에 있습니까?

당신은 시도하고 사용할 수 여기 내 무료 TCP 테스트 클라이언트를 사용하여 문제 공간에서 클라이언트를 제거 할 수 있습니다 마찬가지로 http://www.lenholgate.com/blog/2005/11/windows-tcpip-server-performance.html

를,이 같은 내 간단한 무료 서버 중 하나에 대해 테스트 클라이언트를 테스트 할 수 하나 : http://www.lenholgate.com/blog/2005/11/simple-echo-servers.html

나는 전체 디자인을 제외하고는 분명히 코드에 문제가있는 것을 볼 수 없다.