这更多是一种概念混乱。我正在制作一个多播服务器,它只回显收到的数据报。这是代码
while (1) {
cnt = recvfrom(sock, message, sizeof(message), 0,
(struct sockaddr *) &addr, &addrlen);
//printf("%d \n",cnt);
if (cnt < 0) {
perror("recvfrom");
exit(1);
} else if (cnt == 0) {
break;
}
printf("%s: message = \"%s\"\n", inet_ntoa(addr.sin_addr), message);
addr.sin_addr.s_addr = inet_addr(EXAMPLE_GROUP);
cnt = sendto(sock, message, sizeof(message), 0,
(struct sockaddr *) &addr, addrlen);
if (cnt < 0) {
perror("sendto");
exit(1);
}
}
这个问题是因为多播服务器也会收到数据报。因此,在收到数据报后,它会发送,它再次收到相同的数据报,依此类推进入无限循环。关于如何实现这种类型的服务器的任何指针?
答案 0 :(得分:1)
您需要通过setsockopt().
答案 1 :(得分:0)
一个选项是EJP所说的,禁用组播环回,以便发送机器不会收到自己的组播数据包的副本。但是,请注意,如果您这样做,您将无法再对同一台计算机上运行的客户端和服务器进行测试,因为IP_MULTICAST_LOOP is implemented at the IP routing level。
避免无限数据包循环的第二种可能选择是让echo-server将其响应数据包发送到与其侦听的组播组不同的组播组(或者甚至让它通过单播而不是组播发送其响应;服务器可以调用recvfrom()来查找它收到的任何数据包的单播源地址,因此它很容易知道将回复数据包发回的位置。
第三个选项是以某种方式修改数据包的内容以将其标记为已经看到,以便您的服务器知道不会再次回显它。例如,您可以指定服务器仅回显第一个字节设置为零的数据包,当服务器回显数据包时,它确保在发送()之前将数据包的第一个字节设置为1。出来。 (当然,您的客户需要了解此约定)