我正在开发一个C ++服务器/ .NET客户端应用程序,其中我的服务器(在Linux上运行c ++)广播一条消息,表明它对整个网络都是活跃的,我的.NET程序监听数据包并解析为获得服务器的正常运行时间。
正如我所读到的,要将常规UDP广播发送到广播地址,我只需要将数据包发送到192.168.0.255(在我的情况下为192.168.2.255)或255.255.255.255。这是正确的吗?我可以使用相同的端口地址吗?还有其他必需品吗?
我理解如果我的.NET程序侦听该特定地址,则可以接收来自除我的C ++服务器程序之外的其他应用程序的数据包。是否有任何方法在C ++服务器端“签名”数据包,以便我的.NET程序读取数据包的标题,并看到它(几乎)是我正在寻找的那个?
答案 0 :(得分:27)
无论您使用何种语言,我的答案都是:
关于广播IP地址,两个地址都是广播地址,但有限的广播地址(255.255.255.255)不会被路由器转发。最好使用子网定向广播地址(192.168.2.255)。
要发送/接收广播地址,您需要定义广播地址(广播IP地址和端口号)。例如:192.168.2.255和端口号3000.客户端应用程序(发送者)必须启用SO_BROADCAST套接字选项,如下所示:
int enabled = 1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &enabled, sizeof(enabled));
其中sockfd是套接字描述符。
服务器应用程序将侦听特定端口号(端口3000)。通常,服务器将使用单播消息响应每个请求。
只要没有应用程序正在侦听相同的端口号,就不会发生冲突。除非您启用了SO_REUSEADDRESS套接字选项,否则如果另一个应用程序正在侦听同一端口,则您的服务器将无法运行。但是,如果存在冲突,则您的签名取决于您的协议(邮件格式)。因此,请检查消息格式,如果消息不符合应用程序协议定义的消息格式,请拒绝该消息。
对于客户端应用程序,收到的数据包是单播的(除非您有其他设计)。所以,这方面没有冲突。
答案 1 :(得分:9)
您还必须在C ++中启用SO_BROADCAST套接字选项以发送广播流量,否则您将收到权限被拒绝错误:
int broadcastPermission = 1;
setsockopt(socketDescriptor, SOL_SOCKET, SO_BROADCAST, (void*)&broadcastPermission, sizeof(broadcastPermission))
答案 2 :(得分:3)
如果您的.NET程序侦听广播流量,它将接收在该端口上发送的网络上的所有广播流量,包括您的服务器未发送的流量。您可以在服务器发送的广播消息的有效负载中添加“标记”。这样,您的.NET程序可以区分它关注的是哪些。
除此之外,我建议使用多播而不是广播。广播流量通常仅限于同一子网上的主机。通俗地说,如果您的网络中有路由器,路由器A侧的主机将看不到B侧主机发送的广播流量(反之亦然),因为路由器“阻塞”它。如果主机加入了组播组,路由器几乎总是转发组播流量。