【发布时间】:2021-12-21 07:13:24
【问题描述】:
我正在学习网络编程中的广播(使用 C)。据我了解,发送者向局域网中的所有接收者(正在收听)发送消息。使用我的本地机器和虚拟机,我编写了一个小程序来查看它是如何工作的。
receiver.c 的代码(我将此代码放在本地机器上):
#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/unistd.h>
#define PORT 4242
int main() {
int socket_fd, sender_size;
struct sockaddr_in receiver, sender;
char receive_buff[256], send_buff[256];
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (socket_fd < 0) {
perror("failed to create socket");
return -1;
}
int broadcast_yes = 1, reuse_yes = 1;
if (setsockopt(socket_fd, SOL_SOCKET, SO_BROADCAST, (void*) &broadcast_yes, sizeof(broadcast_yes)) < 0) {
perror("failed to set broadcast socket option");
return -2;
}
if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, (void*) &reuse_yes, sizeof(reuse_yes)) < 0) {
perror("failed to set reuse socket option");
return -3;
}
memset(&receiver, 0, sizeof(receiver));
receiver.sin_family = AF_INET;
receiver.sin_port = htons(PORT);
receiver.sin_addr.s_addr = INADDR_ANY;
if (bind(socket_fd, (struct sockaddr*) &receiver, sizeof(receiver)) < 0) {
perror("failed to bind");
return -4;
}
printf("Listening...\n");
memset(receive_buff, 0, sizeof(receive_buff));
sender_size = sizeof(sender);
if (recvfrom(socket_fd, (void*)receive_buff, sizeof(receive_buff), 0, (struct sockaddr*) &sender, &sender_size) < 0) {
perror("failed to receive broadcast message");
return -5;
}
printf("%s\n", receive_buff);
strcpy(send_buff, "got your message");
if (sendto(socket_fd, (void*)send_buff, sizeof(send_buff), 0, (struct sockaddr*) &sender, sizeof(sender)) < 0) {
perror("failed to send confirmation message");
return -6;
}
close(socket_fd);
return 0;
}
sender.c 的代码(我将此代码放在我的虚拟机上):
#include <stdio.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 4242
int main() {
int socket_fd;
struct sockaddr_in receiver;
char send_buff[256], receive_buff[256];
socklen_t receiver_size;
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (socket_fd < 0) {
perror("failed to create socket");
return -1;
}
int broadcast_yes = 1;
if (setsockopt(socket_fd, SOL_SOCKET, SO_BROADCAST, (void*) &broadcast_yes, sizeof(broadcast_yes)) < 0) {
perror("failed to set broadcast socket option");
return -2;
}
memset(&receiver, 0, sizeof(receiver));
receiver.sin_family = AF_INET;
receiver.sin_port = htons(PORT);
receiver.sin_addr.s_addr = inet_addr("192.168.1.255");
strcpy(send_buff, "i'm sending a broadcast message");
if (sendto(socket_fd, (void*)send_buff, strlen(send_buff) + 1, 0, (struct sockaddr*) &receiver, sizeof(receiver)) < 0) {
perror("failed to send broadcast message");
return -3;
}
memset(receive_buff, 0, sizeof(receive_buff));
receiver_size = sizeof(receiver);
if (recvfrom(socket_fd, (void*)receive_buff, sizeof(receive_buff), 0, (struct sockaddr*) &receiver, &receiver_size) < 0) {
perror("failed to receive confirmation message");
return -4;
}
printf("%s\n", receive_buff);
close(socket_fd);
return 0;
}
如您所见,没有什么花哨的。 sender 将消息i'm sending a broadcast message 作为广播消息发送(因为我将255 放在IPv4 地址的末尾,并且我还在套接字中设置了SO_BROADCAST 选项)。反过来,receiver 等待并接收此消息。它还在套接字中启用了SO_BROADCAST 选项。之后发生的事情让我感到困惑。如上所示,receiver 收到消息后,会向发送者发送一条确认消息got your message。
但是如果一个发送者将消息发送给局域网中的所有接收者(监听者)并且局域网中有多个接收者,这将如何工作?多个接收者中的每一个不会将got your message 确认消息发送给发送者吗?因此,就像多台机器在receiver.c 中有该代码,并且当代码调用函数recvfrom() 时,每台机器都会在变量struct sockaddr_in sender 中获取sender 的地址信息。然后,所有这些机器都会将该消息got your message 发送到sender。但是发件人只有一个recvfrom() 函数调用,所以它只会收到到达它的第一条消息。其他接收者的确认消息将丢失。或者至少这就是我认为将会发生的事情。我该如何解决这个问题并获得所有确认消息?同样,这个问题仅适用于我对上面所说的情况的理解是正确的,我不知道是不是这样,所以我还要问你我认为发件人只会收到一条确认消息是否正确。
【问题讨论】:
标签: c sockets network-programming