2011-12-03 49 views
3

我在我的服務器端下面的代碼:的TcpListener等待方法返回錯誤的值

// Bind to a specific local port number (SERVER_PORT) and any local IP address. 
m_tlServer = new TcpListener(IPAddress.Any, SERVER_PORT); 

// Start listening for connection attempts. 
m_tlServer.Start(); 

// Start accepting new clients. 
// Sleep until a new client(s) will try to connect to the server. 
while (!m_bStopThread) 
{ 
    if (!m_tlServer.Pending()) 
    { 
     // Sleep and try again. 
     Thread.Sleep(LISTENING_SLEEP_TIME); 
     continue; 
    } 
    else 
    { 
     // Accept a new client in a new thread. 
     Thread newthread = new Thread(new ThreadStart(HandleNewConnection)); 
     newthread.Start(); 
    } 
} 

我的問題是,當一個客戶端試圖連接到服務器,Pending返回true幾次(該方法一般爲4次)和幾個線程被創建。 我試圖通過使用AcceptTcpClient方法(不知道是否有任何連接嘗試)的循環替換while循環,它的工作正常。所以,我認爲問題是由Pending方法造成的。 任何人都可以幫助我嗎?謝謝,奧弗。

回答

2

使用AcceptTcpClient而不是Pending它會工作。

爲什麼你在做什麼是生產論文的步驟:

  1. 偵聽器線程掛起看到真正的==
  2. 開始接受螺紋
  3. 偵聽器線程掛起看到真正的==
  4. 開始接受線程
  5. 聽衆線程看到待定== true
  6. 開始接受線程
  7. 首先接收線程開始運行
  8. 偵聽器線程看到待==虛假

概括地說,因爲你開始說一些隨機指令內立即執行一個線程,這不是。線程的要點恰恰是:它將在稍後執行。

如果你想有一個方法來阻止聽的過程中使用WaitHandles

// In your class somewhere stopEvent is a ManualResetEvent 

while(true) 
{ 

    var asyncResult = listener.BeginAcceptTcpClient(null, null); 

    var waitHandles = new [] { stopEvent, asyncResult.AsyncWaitHandle }; 

    var waitResult = WaitHandle.WaitAny(waitHandles); 

    if (waitResult == 0) return; 

    var client = EndAcceptTcpClient(asyncResult); 
    // Create thread to speak with this client 

} 

你的方法,希望停止線程將只需要stopEvent.Set()

+1

@Fuex:事實如此,但池是一個壞主意,應該不惜一切代價避免。我們不需要更多糟糕的編程軟件來佔用計算機的處理器。爲了使用更糟的解決方案,有一種更高效,更快,更簡單的選擇? –

+0

@Fuex能夠終止'accept',你也可以使用回調函數,並在開始時檢查一些'm_stop'變量,但是框架在這種情況下做了什麼基本上是執行我在ThreadPool線程中編寫的代碼並調用你的回調。在這樣一個簡單的例子中,結果是一樣的。但真正的異步IO更強大,因爲同一個線程可能正在等待新客戶端,等待新數據包到達所有客戶端並等待發送數據...(然後運行javascript而不是C#並稱之爲node.js) –

+2

應該有一個「與幽靈說話」的徽章 –