2015-10-20 137 views
0

我想實現簡單的網絡遊戲(客戶端 - 服務器),它使用UDP在網絡上傳輸的遊戲事件,我有這樣的運作良好,但現在我想添加到遊戲中的聊天在同一控制檯應用程序TCP。我試圖使用select()和非阻塞主套接字來實現多客戶端聊天。聊天工作作爲獨立的應用程序,但我有問題把它放在一起。非阻塞選擇()?

基本上我的服務器循環是這樣的:

while(true) 
{ 
    sendUDPdata() 
    ... 

    while(true) 
    { 
     receiveUDPdata() 
    } 
} 

問題是,當我想聊天添加到服務器的主循環(處理UDP)是這樣的:

while(true) 
{ 
    HandleTCPConnections(); 

    sendUDPdata(); 
    ... 

    while(true) 
    { 
     receiveUDPdata(); 
    } 
} 

HandleTCPConnections()調用select()阻止整個服務器。有沒有辦法如何處理這個問題?

+0

'選擇()'有一個超時。您可以使用0秒的超時輪詢所請求的套接字並立即退出而不會阻塞。 –

+0

@RemyLebeau但是他做了什麼?他不能只是再次調用'select'。 –

+0

@DavidSchwartz爲什麼不呢?他可以在一個循環中調用'select()',同時請求TCP和UDP套接字。如果TCP套接字報告它有數據等待,請閱讀它。如果UDP套接字報告它有數據等待,請閱讀它。 'select()'的主要設計之一是在單個線程中處理多個套接字的I/O。 –

回答

4

有兩個很好的方法可以做到這一點:

  1. 使用線程。有一個線程來處理你的TCP套接字和一個線程來處理你的UDP套接字。

  2. 用反應堆。 UDP代碼和TCP代碼都在反應器中註冊它們的套接字。反應器阻塞所有插座(通常使用poll),並在該插座上發生活動時調用適當的代碼。

有很多圖書館在那裏爲這兩個選項(如libeventboost.asio),如果你不想重新發明輪子,你可以使用的。

0

select阻塞調用如果沒有可用的插座的數據,你的情況。

你聊天可以隨着服務器或與它並行運行:你已經拿到了第一種情況;第二,你最好去一個單獨的線程處理聊天。 C++有<thread>,您可能需要查看。

一個單獨的線程更容易在這種情況下實現,因爲你已經一個單獨的連接,以及獨立的插座,因此,原本需要被用於併發訪問的照顧。