2009-10-28 115 views
8

我需要能夠在同一端口上發送和接收UDP數據包。 我可以在端口5000上聽,但我的發送使用隨機高端口。 我正在使用VB編寫的系統執行此操作,我的需求是編寫一個UDP響應程序來調試各種協議問題。如何在同一端口上發送和接收UDP?

我使用的開源C++庫套接字從http://www.alhem.net(安德斯Hedstrom),並已經能夠使用UdpSocket :: bind()的接收使用虛擬函數UdpSocket :: OnRawData()傳入的UDP數據包,但有無法導致UdpSocket :: Open()(調用connect)使UdpSocket :: Send()使用在Bind()中選擇的端口(它使用隨機高數字端口)。

移動Open()函數沒有幫助。我已經在他們的論壇上發佈了一個請求 - 但是從我讀到的內容來看,應該可以做到這一點,而且我可能不瞭解如何使用UDP。

有沒有人有什麼想法我應該嘗試?
- 謝謝 -

+0

你是在同一個UdpSocket對象還是兩個不同的對象上調用Bind()和Open()? – 2009-10-28 23:03:08

+0

調用Bind(),然後打開(),然後使用相同的實例化對象發送()。 – cedgriss 2009-10-28 23:40:33

回答

3

雙向通信鏈接始終涉及兩個參與者:服務器端和客戶端。

客戶端希望在定義的端口上與服務器通信:這就是爲什麼在服務器端必須綁定()到套接字。

在客戶端,必須打開一個到服務器的套接字:選擇哪個套接字(除非需要它是空閒的)並不重要。

換句話說,不要試圖在客戶端指定套接字:網絡協議棧會將其分配給客戶端。

+0

系統由監聽同一端口的多個節點組成(不同的IP地址)。系統[A]發送數據報到系統[B]。系統[B]異步響應,並使用相同的端口將數據報發送回[A]。即使[B]識別[A]的端口,[A]也不在該端口上偵聽。我正在爲診斷和測試開發一個協議測試/響應器,並且必須能夠作爲一個從相同端口#監聽和發送的子系統出現。我無法改變現有系統,這些系統都是現有標準化實施的一部分。 – cedgriss 2009-10-28 23:50:24

+0

你能畫一張圖嗎?會讓事情變得更簡單(至少對我來說)。 – jldupont 2009-10-29 23:00:50

8

系統由多個監聽相同的端口(不同的IP地址 的)節點 的。系統[A]發送數據報到 系統[B]。系統[B]異步 響應併發送數據報回到 [A]全部使用相同的端口。即使[B] 識別[A]的端口,[A]是不是 監聽端口

上我不知道我理解那句話‘一切使用同一端口’這句話。如果A向B發送數據報,B將立即知道A的IP和端口(通過快速檢查您的庫文檔,可以發現OnRawData具有struct sockaddr *sa參數,如果將其轉換爲sockaddr_in*,則可以提取IP:端口對)。您可以使用該IP:端口發送數據報,而A將接收它們。 A沒有在該端口上「偵聽」,因爲它沒有在套接字上調用listen(),但是由於A擁有一個綁定到該端口的套接字(無論是通過調用bind()還是通過分配隨機端口OS)它將接收數據。

現在,如果您希望節點之間的所有通信都通過固定端口,那麼您可以這樣做。你只需要通過你的「監聽」套接字發送你所有的數據報。如果每個節點都在同一個端口上「偵聽」,這意味着每個節點都擁有一個綁定到該端口的套接字。如果您希望從A發送到B的數據報顯示來自此固定端口,則必須通過該套接字發送它們。我猜這就是爲什麼bind()不適用於你的發送套接字 - A有一個綁定到端口X的套接字,然後你創建另一個套接字並嘗試將它綁定到同一個端口X,bind()因爲端口已經被採用了(並且你不檢查錯誤:),然後OS分配1024以上的隨機空閒端口。注意1:我在所有地方都使用「聆聽」引號,因爲這個概念在UDP套接字的上下文中並不十分清楚。創建套接字並將其綁定到端口後,可以通過顯式調用bind()或通過發送數據並讓操作系統將其綁定到端口來實現,您可以通過它從任何地方接收數據。不需要listen()或accept()調用。注意2:你說UdpSocket :: Open()調用connect(),但這沒有多大意義 - connect()對UDP套接字做的很少 - 它只是建立一個默認地址,所以你可以使用send()而不是sendto()並且不指定每個發送的地址。

希望能夠解決問題。


編輯到地址OP的評論:我從來沒有使用過這個庫,但根據他們的 UdpSocket documentation Bind()方法有4個重載,並且它們中的每一個都以某種方式接受端口。他們都不適合你嗎?

+0

優秀的答案。 – aib 2009-10-29 11:55:50

+0

感謝您的回覆。先前的嘗試表明您的筆記是正確的。 更多研究表明,我必須將傳遞給低級別bind()函數的低級struct sockaddr *地址的sin_port字段從「0」更改爲我所需的源端口(「0」表示使用可用端口作爲src發送)。我正在通過代碼,還沒有找到一種方法來使用高級別的UpdSocket對象來訪問和更改它。我還不確定自己是否正確,並希望圖書館有辦法做到這一點。 – cedgriss 2009-10-29 12:08:06

+0

重新檢查UpdSocket :: Bind(),雖然所有都指的是設置傳入/接收,但第4個版本使用SocketAddress&struct也可能有發送端口。我會更深入地研究它,然後回顧一下。再次感謝您的快速響應。 – cedgriss 2009-10-29 13:45:56

相關問題