我想询问是否有可能,以及我是如何从我的UDP服务器向客户端发送广播,之后将回复从客户端发送回服务器。
我需要实现一个应用程序,其中服务器在子网上发送广播,客户端应该以某种方式接收该消息,并以这种方式获取服务器地址以便他们可以将一些消息发送回服务器。
我创建了一个指定服务器端口为2000的套接字并将setsockopt
设置为SO_BROADCAST
并发送了一条消息sendto
但我的客户端永远挂起recvfrom
。似乎它没有从服务器的广播中收到任何东西。如何解决这个问题?
服务器
struct sockaddr_in addr;
int socketfd,t=1;
socketfd = socket(PF_INET,SOCK_DGRAM,0);
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons("2000");
addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
if (setsockopt(socketfd, SOL_SOCKET, SO_BROADCAST ,&t, sizeof(t)))
ERR("setsockopt");
if(bind(socketfd,(struct sockaddr*) &addr,sizeof(addr)) < 0)
ERR("bind");
char *buf = "HelloFromServer!";
if(sendto(socketfd, buf, strlen(buf), 0, (struct sockaddr *)&addr, sizeof(addr)) <= 0)
{
perror("something went wrong..");
return EXIT_FAILURE;
}
客户端:
struct sockaddr_in addr;
int socketfd,t=1;
socketfd = socket(PF_INET,SOCK_DGRAM,0);
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons("2000");
addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
if (setsockopt(socketfd, SOL_SOCKET, SO_BROADCAST ,&t, sizeof(t)))
ERR("setsockopt");
char data[12];
struct sockaddr_in serv_addr;
socklen_t size=sizeof(serv_addr);
recvfrom(fd, (char *)data, sizeof(char[12]), 0, &serv_addr, &size);
我的客户端挂起了这个recvfrom ...因此我无法存储 serv_addr ,以便我可以将一些消息发送回服务器
答案 0 :(得分:1)
客户端应该以某种方式接收该消息,并以这种方式获取服务器地址,以便他们可以将一些消息发送回服务器。
我认为这里存在一个问题:为了让客户端接收服务器广播的消息,他们必须首先拥有服务器的地址。套接字唯一可以从未知地址接收数据/通信的时间是在端口上使用listen()
的服务器,该端口设置了端口转发(由路由器提供)。因此,除非客户端已经拥有服务器地址,否则似乎客户端无法接收数据,因此挂起recvfrom()
。
答案 1 :(得分:1)
服务器和客户端的错误都在
中 addr.sin_port = htons("2000");
htons()
采用整数,而不是字符串。写
addr.sin_port = htons(2000);
代替。