我想问是否有可能,如果有的话,我如何从我的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存储,以便我可以将一些消息发送回服务器
客户端应该以某种方式接收该消息,并以这种方式获取服务器地址,以便他们可以将一些消息发送回服务器。
我认为这里有一个问题:对于客户端接收服务器广播的消息,他们必须首先拥有服务器的地址。套接字可以从未知地址接收数据/通信的唯一时间是服务器在端口上使用listen()
,该端口设置了端口转发(由路由器提供)。因此,除非客户端已经有了服务器地址,否则客户端接收数据似乎是不可能的,因此挂起了recvfrom()
。
服务器和客户端的错误都在
addr.sin_port = htons("2000");
htons()
接受整数,而不是字符串。写
addr.sin_port = htons(2000);
。