2011-06-16 104 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))