2013-08-27 35 views
1

注:我不問如何使用多播或廣播的整個會話,只爲握手TCP組播初始化僅

我想知道是否一個想法,我可以在Linux程序中實現而不對內核做任何改變。或者,如果修改內核實際上是必要的,我想知道需要編輯哪些文件。它的基本思想是:「客戶端」向一個廣播或多播地址發送一個TCP SYN數據包,然後調用accept()或等價物爲它返回的每個SYN-ACK打開一個單獨的文件描述符。

理想情況下,我想使用修改的握手,然後切換回標準的TCP方法,但如果這是不可能的,我不介意使用另一個線程並使用unix域套接字來模擬它。

+1

組播不能與TCP一起使用。 – Barmar

+0

如果你想這樣做,因爲你不知道服務器的IP,有標準的服務器發現協議。 – Barmar

+1

TCP不支持多播地址,這是互聯網規範。 – Barmar

回答

2

多點傳送TCP與TCP規範不兼容。 RFC 1122 section 4.2.3.10說:

A TCP implementation MUST reject as an error a local OPEN call for an invalid remote IP address (e.g., a broadcast or multicast address).

An incoming SYN with an invalid source address must be ignored either by TCP or by the IP layer (see Section 3.2.1.3).

A TCP implementation MUST silently discard an incoming SYN segment that is addressed to a broadcast or multicast address.

的基本問題是,SYN-ACK應答的源地址必須與原始SYN數據包的目標地址相匹配 - 這是回答如何與原來的連接請求匹配(除了將目標地址與原始源地址匹配以及匹配端口號)。但爲了在握手後切換到單播,您需要知道服務器的真實地址。

你可以,我想,增強協議來添加一個包含這個地址的TCP選項。或者你可以說,當SYN被髮送到一個多播組時,匹配的源地址在匹配時被忽略 - 這意味着端口號本身可以唯一地定義多播連接請求。如果你對此感興趣,也許你應該爲它寫一個規範,並將它提交給IETF作爲協議增強。

但是已經有一些協議用於查找網絡上的服務器,比如Bonjour。服務器也可以在DNS或Active Directory中列出。你的想法聽起來不像是它完成了任何尚不可用的事情。

0

使TCP有多個客戶端是不平凡的任務!這是一些原因。首先,如果有多個接收者,那麼你如何跟蹤哪些發送速率用於誰。其次,如果多個接收者錯過了一組數據包,那麼您如何重新傳輸這些數據包。第三,如果接收者通告給定的接收緩衝區(又名流量控制),您選擇哪一個緩衝區 - 您是否選擇公佈最小的緩衝區並讓其他人受到影響,或者您是否選擇平均值,只讓部分接收機受損。最後,TCP是面向連接的,所以即使你破解內核來做這件事,像send()/ recv()這樣的普通套接字調用也不知道客戶端發送或接收到的是什麼。你可以嘗試使用sendto()/ recvfrom(),但是到目前爲止,內核通常會忽略這些調用中的地址。

你可能會更好建立在「只爲握手組播」 TCP

+0

嘗試閱讀實際問題:我特別提到了每個接收到的每個SYN + ACK數據包都有一個單獨的連接 –

+0

我站得更正 - 謝謝!我可能受到一些答案的影響!正如其他人所提到的,TCP在內核中的實現不允許爲connect()調用傳遞多播地址。所以,你肯定會修改內核。您可以在這裏瀏覽TCP文件:http://lxr.free-electrons.com/source/net/ipv4/。 –

+0

順便說一句,我很快編寫了一個TCP客戶端,併爲connect()調用傳遞了一個多播地址。我收到以下錯誤:「連接失敗[協議族不支持的地址族]」。上述錯誤源於此處的tcp_v4_connect()函數http://lxr.free-electrons.com/source/net/ipv4/tcp_ipv4.c#L142 –

1

這肯定會需要重大的內核更改。它也完全與TCP RFC不兼容,所以你要實現的不會是TCP。

應該編輯哪些文件? TCP內核實現文件。但是你首先需要很好地理解Linux的TCP如何工作,這超出了Stackoverflow的答案。

但是,爲什麼不去尋找更簡單的解決方案?
使用UDP組播,向所有潛在合作伙伴發送消息。每個人都將通過UDP回覆其IP和端口號。然後打開所有這些連接的常規TCP連接。