首页 文章

C UDP广播使用:: write

提问于
浏览
0

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

我的客户端基本上与http://man7.org/linux/man-pages/man3/getaddrinfo.3.html的客户端示例一样,即它使用connect()函数指定所有传出数据包的 endpoints . 通过使用连接的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 回答

  • 1

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

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

相关问题