簡體   English   中英

將多個客戶端連接到服務器的好方法是什么?

[英]What is a good way to connect multiple clients to the server?

由於有多種方法可以將多客戶端連接到服務器,例如:fork,select,threads等。如果您能描述將多個客戶端連接到服務器哪個更好,我會很高興嗎?

查看C10K頁面,了解I / O框架和策略的概述和比較。

設計一些心跳循環,它將遍歷所有套接字並響應各自的事件。

我建議服務器是被動的(客戶端將連接到它,而不是連接到客戶端的服務器),因為它通常在Web上完成。 因此,它還將有一個監聽器套接字。

一個簡單的建議,避免使用fork,因為它創建了一個重量級的進程,使用更輕的線程,並分享與之創建的進程相同的內存空間。

至少有兩種選擇。

  • 創建一個偵聽套接字。
  • 等待連接。
  • 產生一個線程來處理連接。

要么

  • 創建一個listen套接字並使用select()等待它。
  • 如果監聽套接字fd變為活動狀態,則建立新連接並將新fd添加到選擇呼叫。
  • 如果連接fd變為活動狀態,請處理它。

如果你了解線程,第一種選擇可能是更簡潔的方法。 第二種方法需要一些fd管理(例如監聽或連接),但可以在單個線程中完成。

what do you mean by this <<the first alternative might be a cleaner approach>>? can you explain pls?

如果您了解線程之間的線程和同步,則第一種方法可以更簡單,因為您可以使用常規阻塞讀取和寫入連接套接字。

第二種方法要求您使用非阻塞讀/寫並處理部分數據包,如果您希望能夠同時處理所有客戶端。

我在C中知道fd_select提供了這種套接字能力的輪詢。 不確定,但我猜測C#有更好的方法。

如果您的程序在Windows上運行 完全避免線程和進程,並使用套接字編程的異步模型。 到目前為止,這是進行網絡通信的最有效(也是最簡單的方法)。

如果您使用的是Windows,那么處理大量客戶端的最有效方法是圍繞異步I / O和I / O完成端口構建服務器。 這些允許您以有效的方式為少量(4?)線程的許多(10‰)客戶端提供服務。

有些人發現I / O完成端口模型的異步性質有點難以理解但我有一個免費的C ++源代碼框架,您可以從這里下載以開始。 如果您正在使用托管代碼,那么.Net框架中的所有異步套接字API都會使用“引擎蓋下的I / O完成端口”。

I / O完成端口模型可以很好地擴展,因為它是一個從頭開始構建的操作系統原語,效率很高; 它知道與之關聯的線程是否正在運行或等待,因此可以管理它允許同時處理“完成”的線程數。 它還以fifo順序使用線程,這樣如果沒有什么工作要做,那么浪費的上下文切換就會減少,因為只會使用最少數量的線程(而不是在所有線程中調度工作項並導致所有堆棧保持分頁到內存中)。 相比之下,您自己的線程池必須效率較低,因為您沒有與IOCP相同的線程知識水平。 選擇通常會受到它可以支持的套接字數量的限制,這意味着為了實現真正的可擴展性,您需要在select之上構建一些復雜的代碼,以便能夠管理超過此數量的客戶端。 使用每個連接模型的線程效率要低得多,因為不僅新的線程會定期啟動和停止,而且您在任何時候都無法控制進程中的線程數 - 當您考慮因素時線程是相對較重的資源一旦你有比CPU內核更多的線程,你就會在上下文切換中浪費時間(IOCP通常會完全避免)。 最后,為每個連接分配一個新進程比每個連接模型的線程更重,並且我個人認為沒有理由認為這是現代操作系統上的有效選項。

Unix網絡編程第30章介紹了客戶端/服務器設計的替代方案。 UNP一書是網絡編程的最佳起點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM