2011-06-16 232 views
12

我正在C++服務器/ .NET客戶端應用程序對中工作,其中我的服務器(在Linux上運行C++)廣播一條消息以顯示它對整個網絡是活着的,我的.NET程序偵聽數據包並解析以獲取服務器的正常運行時間。網絡UDP廣播設計?

正如我已經閱讀,要發送一個普通的UDP廣播到廣播地址,我只需要發送一個數據包到192.168.0.255(在我的情況下192.168.2.255)或255.255.255.255。這是正確的嗎?我可以使用相同的端口地址嗎?還有其他的必需品嗎?

我明白,如果我的.NET程序在該特定地址上偵聽,則可能接收來自除C++服務器程序之外的其他應用程序的數據包。有沒有在C++服務器端「簽名」數據包的方法,以便我的.NET程序能夠讀取數據包的標題,並且看到它(幾乎)是我正在尋找的那個?

回答

20

無論您所使用的語言,這裏是我的答案:

關於廣播IP地址,兩個地址都是廣播地址,但有限廣播地址(255.255.255.255)不會被路由器轉發。最好使用子網定向廣播地址(192.168.2.255)。

爲了發送/接收廣播地址,您需要定義您的廣播地址(廣播IP地址和端口號)。例如:

int enabled = 1; 
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &enabled, sizeof(enabled)); 

其中的sockfd是套接字描述符:192.168.2.255和端口號3000的客戶端應用程序(發送方),如下所示,必須啓用SO_BROADCAST套接字選項。

服務器應用程序將偵聽特定端口號(端口3000)。通常,服務器將使用單播消息響應每個請求。

只要沒有應用程序監聽相同的端口號,就不會有衝突。除非啓用SO_REUSEADDRESS套接字選項,否則如果其他應用程序正在偵聽相同端口,則服務器將不會運行。但是,如果有衝突,那麼您的簽名取決於您的協議(消息格式)。因此,如果消息格式不符合應用程序協議定義的消息格式,請檢查消息格式並拒絕消息。

對於客戶端應用程序,接收到的數據包是單播的(除非您有其他設計)。所以,在這方面沒有衝突。

+0

那麼,基本上,在客戶端,我聽本地IP端口x? – 2011-06-16 19:21:50

2

如果您的.NET程序監聽廣播流量,它將接收在該端口上發送的網絡上的所有廣播流量,包括未由服務器發送的流量。您可以在服務器發送的廣播消息的有效載荷中放置一個「標記」。這樣,你的.NET程序可以區分它關心的是哪一個。

除此之外,我會建議使用多播而不是廣播。廣播流量通常僅限於同一子網上的主機。通俗地說,如果您的網絡中有路由器,路由器A側的主機將看不到B側主機發送的廣播流量(反之亦然),因爲路由器會「阻止」它。如果主機已加入多播組,則路由器幾乎總是會轉發多播流量。

7

你還必須能夠在C++中SO_BROADCAST套接字選項發送廣播流量,否則你會得到一個權限被拒絕的錯誤:

int broadcastPermission = 1; 
setsockopt(socketDescriptor, SOL_SOCKET, SO_BROADCAST, (void*)&broadcastPermission, sizeof(broadcastPermission))