2010-02-14 55 views
4

我正在寫一個服務器,應該是爲了提供API的linux。多線程服務器問題

最初,我想讓它在單個端口上多線程,這意味着我有多個線程可以處理單個端口上接收到的各種請求。

我的一位朋友告訴我,它不是它應該工作的方式。他告訴我,收到請求後,我首先必須遵循Handshake過程,創建一個線程正在監聽專用於請求的其他端口,然後將請求的客戶端重定向到新端口。

從理論上講,這很有趣,但我找不到任何關於如何實現握手和重定向的信息。有人可以幫忙嗎?


如果我沒看錯解釋你的反應,一旦我創建了一個多線程的服務器與主線程監聽的端口,並創建一個新的線程來處理請求,我基本上是使其在多線程一個端口?

考慮一下我每秒都會收到大量請求的場景。是不是每個端口上的請求現在都應該等待「當前」請求完成?如果不是,那麼通信仍將如何完成:假設瀏覽器發送請求,因此處理該請求的線程必須先監聽端口,阻止端口,處理它,響應並解除阻塞。因此,雖然我有「多線程」,但我使用的是除主線程以外的一次單線程,因爲端口被阻塞。

+0

兩個(或多個)連接可同時處於活動狀態到同一本地端口 - 這絕對沒有錯,而且這是事情常用的方式。一個連接不會「阻止」其他任何連接 - 一旦創建,它們就完全獨立。 – caf 2010-02-15 00:54:08

+0

嗨。感謝您的評論。我完全明白你的觀點,事實上,我正在混淆。如果多個連接正在使用一個端口,意味着兩個不同的客戶端正在連接相同的端口,那麼讀寫操作將如何正確完成以及信息如何發送到正確的客戶端? 我試過閱讀一些關於套接字和服務器編程的書籍/文章,但意識到我在錯誤的地方尋找解決方案。任何人都可以提出一個關於這個主題的整齊小巧的指南嗎? – 2010-02-16 03:08:50

+1

從應用程序的角度來看,這兩個連接由不同的套接字表示 - 不同的文件描述符。從傳輸的(TCP/IP)角度來看,這兩個連接由不同的(遠程IP,遠程端口,本地IP,本地端口)元組來標識(一個或兩個遠程部分地址將會不同)。 – caf 2010-02-17 06:59:56

回答

2

你的朋友告訴你的東西類似於被動FTP - 客戶端告訴服務器它需要連接,服務器發回端口號,客戶端創建到該端口的數據連接。

但是你想要做的只是一個多線程服務器。所有你需要的是一個服務器套接字監聽和接受給定端口上的連接。自動TCP握手完成後,您將從accept函數獲得一個新套接字 - 該套接字將用於與剛剛連接的客戶端進行通信。所以現在你只需要創建一個新的線程,將該客戶端套接字傳遞給線程函數。在您的服務器線程中,您將再次調用accept以接受另一個連接。

2

如果您認爲沒有任何理由進行握手而不是您的應用程序不需要它,TCP/IP會進行握手。

應用程序特定握手的一個示例可以用於用戶身份驗證。


你的同事提出的建議聽起來像FTP的工作方式。這不是一件好事 - 現在的互聯網或多或少地用於使用單個端口的協議,並且命令端口不好。其中一個原因是因爲有狀態防火牆不是爲多端口應用設計的;他們必須針對每個單獨的應用程序進行擴展,以這種方式執行任務。

1

看看ASIO's tutorial on async TCP。有一部分接受TCP上的連接,併產生每個與單個客戶端進行通信的處理程序。這就是TCP服務器通常的工作方式(包括HTTP/web,最常見的tcp協議)。

如果設置爲每個連接創建線程,您可以忽略ASIO的異步內容。它不適用於你的問題。 (完全異步並且每個核心有一個工作線程是很好的,但它可能無法與其他環境完美集成。)