使用:: write的C ++ UDP广播

时间:2018-05-30 15:20:51

标签: c++ linux sockets udp broadcast

我正在编写UDP客户端/服务器应用程序。服务器是广播服务器,它在特定端口上广播到同一子网上的两个客户端。每个客户端都会收到一个数据报并向服务器发送响应。每个客户端都事先知道服务器的IP地址。

我的客户端基本上与http://man7.org/linux/man-pages/man3/getaddrinfo.3.html的客户端示例相同,即它使用connect()函数指定所有传出数据包的端点。通过使用连接的UDP,客户端可以使用read()和write()到套接字文件描述符而不是sendto / recvfrom。

对于我的服务器,我想采用类似的方法 - 配置广播套接字,并在文件描述符上调用读/写。我可以bind()套接字来监听指定端口上的传入数据报,并且这些数据集收集得很好。

减去错误检查,我的服务器代码如下所示:

int sockfd = socket(AF_INET, SOCK_DGRAM, 0);

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

struct sockaddr_in servaddr;
memset((char*) &servaddr, 0, sizeof servaddr);
servaddr.sin_family = AF_INET;
servaddr.sin_port   = htons(PORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

int success = bind(sockfd, (struct sockaddr*) &servaddr, sizeof servaddr);

int BUFSIZE = 256;
char buf[BUFSIZE];

while (1)
{
    // this works fine
    int bytes_read = read(sockfd, buf, BUFSIZE);

    // WANT TO BROADCAST HERE
    int bytes_written = write(sockfd, buf, bytes_read); 
}

然而,当我尝试在write()行中广播一个数据包时,我得到一个未指定的目标地址'错误。我可以调用connect()来设置目标地址,但我不认为connect()适用于广播套接字。

有没有使用write()而不是sendto进行广播的方法?

1 个答案:

答案 0 :(得分:1)

使用connect()进行广播的问题是(除了修改send()/ write()的行为外),connect()将在套接字上安装一个过滤器,以便它只接收源 - IP字段匹配connect()参数中指定的IP地址。

这意味着如果您使用广播地址作为其参数调用套接字上的connect(),那么您的套接字将只接收来自该广播地址的数据包 - 但数据包永远不会(AFAIK)被标记为来自广播地址 - 而不是像往常一样将其Source-IP字段设置为发送数据包的计算机的IP地址。结果是,如果你将你的套接字连接到广播地址,你就不会在该套接字上收到任何数据包。