19

我正在开发一个 C++ 服务器/.NET 客户端应用程序对,其中我的服务器(在 linux 上运行 c++)广播一条消息以表明它对整个网络是活跃的,我的 .NET 程序侦听数据包并解析以获得正常运行时间服务器的。

正如我所读到的,要将常规的 UDP 广播发送到广播地址,我只需将数据包发送到 192.168.0.255(在我的情况下为 192.168.2.255)或 255.255.255.255。这是正确的吗?我可以使用相同的端口地址吗?还有其他必需品吗?

我理解这样一个事实,即如果我的 .NET 程序侦听该特定地址,则可以从我的 C++ 服务器程序以外的其他应用程序接收数据包。是否有任何方法可以在 C++ 服务器端“签名”数据包,以便我的 .NET 程序读取数据包的标头并查看它(几乎)是我正在寻找的那个?

4

3 回答 3

31

无论您使用哪种语言,这都是我的回答:

关于广播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 套接字选项。但是,如果存在冲突,那么您的签名取决于您的协议(消息格式)。因此,请检查消息格式并拒绝该消息,如果它不符合您的应用程序协议定义的消息格式。

对于客户端应用程序,接收到的数据包是单播的(除非您有其他设计)。所以,这边没有冲突。

于 2011-06-16T16:01:15.033 回答
9

您还必须在 C++ 中启用 SO_BROADCAST 套接字选项来发送广播流量,否则您将收到权限被拒绝错误:

int broadcastPermission = 1;
setsockopt(socketDescriptor, SOL_SOCKET, SO_BROADCAST, (void*)&broadcastPermission, sizeof(broadcastPermission))
于 2011-06-16T15:46:33.890 回答
3

如果您的 .NET 程序侦听广播流量,它将接收在该端口上发送的网络上的所有广播流量,包括不是由您的服务器发送的流量。您可以在服务器发送的广播消息的有效负载中放置一个“标记”。这样,您的 .NET 程序可以区分它关心的那些。

除此之外,我建议使用多播而不是广播。广播流量通常仅限于同一子网上的主机。通俗地说,如果您的网络中有路由器,则路由器 A 侧的主机将看不到 B 侧主机发送的广播流量(反之亦然),因为路由器“阻止”了它。如果主机加入了多播组,路由器几乎总是会转发多播流量。

于 2011-06-16T15:27:28.143 回答