2012-02-07 171 views
1

我在C和Linux中實現了TCP套接字服務器。它將是一個同時處理多個請求的聊天服務器。下面是它是如何設置C/Linux TCP套接字服務器

create a socket 
bind to a well-known port 
use listen to place in passive mode 
while (1) 
{ 
    accept a client connection 
    fork 
    if (child) 
    { 
     communicate with new socket 
     close new socket 
     exit 
    } 
else 
{close new socket} 
} 

從我所看到的僞代碼中,「新窩溝通」部分包括讀取緩衝區,然後可能寫入緩衝區,然後插座關閉。我認爲套接字被認爲是一個持久的連接?如果客戶端每次想要向服務器發送更多數據時都必須重新連接,這是否是低效的並且會影響套接字的目的?

+1

是你的功課嗎? – 2012-02-07 10:36:41

+1

你應該使用諸如libevent或libev之類的事件庫。 – 2012-02-07 11:42:42

+0

您不需要爲每個客戶端「分叉」。你很可能需要一個圍繞多路複用系統調用的事件循環,比如'select'或'poll'(或者一個帶有事件循環的庫,比如'libev'或'libevent'或者別的東西;並且這個庫會執行多路複用)。 – 2012-02-07 12:30:04

回答

2
  1. 請勿關閉插座。將接收和響應消息的代碼放在一個循環中,並使用阻塞I/O(缺省值)在讀取套接字時阻塞,直到請求到達。通過這種方式,您將擁有一個處理每個客戶端並使用最少資源的分叉進程。您只關閉套接字並在客戶端顯式關閉連接時退出子進程,因爲它已完成。

  2. 使用UDP而不是TCP。這樣服務器和客戶端之間就沒有「連接」。您將多個客戶端多路複用到一個套接字而不分叉。如果您關心可靠性,您需要爲每條消息添加一個序列號以保持它們的直線性,並允許在發生故障時進行重新傳輸。

  3. 保留使用TCP的單個進程,但存儲套接字描述符集並使用select檢查可讀的套接字。然後,您可以在每個或某些其他客戶端套接字上重新傳輸該數據。

我想指出,在聊天服務器中爲每個客戶端分派一個孩子似乎是一個糟糕的實現。兩個想聊天的人如何交流?每個人都將通過一個獨立的流程進行服務 - 流程如何相互通信,以便聊天數據可以在客戶端之間傳遞?

+0

「如果你關心可靠性,你需要爲每條消息添加一個序列號,以保持它們的直線性,並允許在發生故障時重新傳輸。「< - 這叫做TCP ... – m0skit0 2012-02-07 10:58:24

+0

2.如果你需要可靠性,甚至不要考慮使用UDP,除非你有非常充分的理由這樣做(有一些用例,但這是相當先進的水平) – 2012-02-07 10:59:43

+0

在需要大量速度和無法識別的情況下使用UDP,例如管理共享多人遊戲的客戶端的服務器。如果使用TCP,則數據包流速緩慢,因此反應速度很慢。用於廣播信息 – Eregrith 2012-02-07 11:13:45

3

如果客戶端每次要將更多數據發送到服務器時都需要重新連接,是不是這樣低效並且會影響套接字的目的?

這是不可能不知道更多關於你的應用程序的性質,說:

  • 在某些情況下,它是有道理的,以保持對客戶的生命週期內的持久連接。

  • 在其他情況下,連接每條消息也會很好。

你在效率方面是非常正確的:在建立TCP連接時存在相當多的開銷。因此,如果消息頻繁出現,爲每條消息設置新的連接可能會非常昂貴。