2012-12-29 98 views
0

客戶端需要同時建立到服務器的多個tcp連接。 我的服務器的代碼如下。Tcpclient多個客戶端連接到服務器

while (_running) 
{ 
    if (!_listener.Pending()) 
    { 
     Thread.Sleep(100); 
     continue; 
    } 

    TcpClient client = _listener.AcceptTcpClient(); 
} 

而我的客戶的代碼如下。

for (int i = 0; i < num; i++) 
{ 
    TcpClient tcp = new TcpClient(); 
    tcp.Connect(_server); 
} 

第一個連接就是成功。但由於服務器沒有響應,第二個連接失敗(實際上服務器正在偵聽TCP連接)。
但是,如果我在每個tcp.Connect()之後添加Thread.Sleep(1500),則所有連接都會成功。但是這種情況只有在有一個客戶端和一個服務器時纔是正確的。如果客戶端很多,那麼我怎樣才能確保服務器可以接受的每個連接?另外爲什麼我添加Thread.Sleep可以使這種連接成功?

回答

0

我有同樣的任務。我尋找這個任務的規範執行.Net沒有運氣。 我現在使用的方法如下所述。

主要思想

我們需要監聽器接收連接,給處理程序的連接,並儘快開始監聽新的連接。

實施

AutoResetEvent _stopEvent = new AutoResetEvent(false); 
object _lock = new object(); 

public void StartListening() 
{ 
    _listener.BeginAcceptTcpClient(ConnectionHandler, null); 
    _stopEvent.WaitOne();//this part is different in my original code, I don't wait here 
} 

public void StopListening() 
{ 
    lock(_lock) 
    { 
     listener.Stop(); 
     listener = null;     
    } 

    _stopEvent.Set();//this part is different in my original code 
} 

void ConnectionHandler(IAsyncResult asyncResult) 
{ 
    lock(_lock) 
    { 
     if(_listener == null) 
      return; 

     var tcpClient = _listener.EndAcceptTcpClient(asyncResult); 
     var task = new MyCustomTask(tcpClient); 
     ThreadPool.QueueUserWorkItem(task.Execute); 

     _listener.BeginAcceptTcpClient(ConnectionHandler,null);    
    } 
} 

我現在還不能在ConnectionHandler調用_listener.BeginAcceptTcpClient非常有信心,但我還沒有找到替代方法。

0

由於仍然沒有滿意的答案,我最終使用不同的方法來處理我的情況。我發現使用類Socket比使用TcpListenerTcpClient更快,更穩定。我嘗試了使用TcpListenerTcpClient的不同方法。首先,我用TcpListener.AcceptTcpClient來聽客戶端有沒有TcpListener.Pending,但仍有可能忽略某些客戶端連接。其次,我使用了異步方法TcpListener.BeginAcceptTcpClientTcpListener.EndAcceptTcpClient,但仍然沒有成功,仍然忽略某些客戶端連接。最後使用Socket.Accept而不是TcpListener.AcceptTcpClient,前者幾乎沒有延遲,並且對客戶端的響應速度非常快。

+3

接受客戶端的延遲是由於代碼中的浪費,而不是API中的任何缺點。 – EJP