1

我尝试在我的应用程序中绑定多播端口。以前代码总是有效,但在这个服务器上它(经常,但不总是)失败......

错误消息是Address already in use,我不太明白,因为可以绑定来自多个应用程序(甚至来自同一个应用程序)的相同地址......

什么可能导致这种情况?我知道有人会要求它,所以这里是代码:

int fd = socket(PF_INET, SOCK_DGRAM, 0);
/* yes, that's a valid socket, verified.... */

u_int val = 1;
if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
    perror("Reusing ADDR failed");
    exit(1);
}

struct sockaddr_in saddr;
saddr.sin_family = PF_INET;
saddr.sin_addr.s_addr = inet_addr(multicast_group_ip);
saddr.sin_port = htons(port);
/* yes, valid multicast ip address and port, verified */

if(bind(fd, (struct sockaddr *) &saddr, sizeof(struct sockaddr_in)) == -1)
    //FAILS....
4

2 回答 2

3

您实际上可以将多个数据报套接字绑定到同一个多播组和端口。但是,所有这些套接字都应该设置 SO_REUSEADDR 选项。根据您的代码,您似乎正在这样做,但听起来您的服务器上有另一个进程已将套接字绑定到相同的多播组和端口,而没有设置该选项。解决方案是确保此特定服务器上将套接字绑定到该多播组和端口的所有进程都设置 SO_REUSEADDR 选项。

编辑:
为了回应您上面最近的评论,您可以实际重现此问题的一种方法是创建两个简单的多播侦听程序,它们都将数据报套接字绑定到相同的端口和组。让其中一个程序设置 SO_REUSEADDR 选项,而不是另一个。运行没有设置 SO_REUSEADDR 的程序,您应该会看到多播数据通过。在离开这个程序的同时,运行第二个设置了 SO_REUSEADDR 的程序,您应该看到它不会在第一个程序仍在接收它时接收任何多播数据(这应该会复制您最初描述的问题)。

最后关闭两个程序,然后修改第一个程序设置SO_REUSEADDR,重复上述步骤。您现在应该看到两个程序都接收到多播流量。

于 2016-11-23T15:49:32.887 回答
0

一个进程可能有多个打开的套接字host:port,不可能有多个进程正在侦听(即绑定)同一个host:port.

也许,您之前的服务器进程实例未被杀死。

Wug 提到的另一个选项是您尝试绑定到低于 1024 的端口而不是 root。低端口 1-1024 的范围是为有效 UID == 0 的应用程序保留的,例如,由 root 启动。似乎是错误的假设,因为在这种情况下你会得到不同的错误,而不是already in use.

于 2012-10-04T19:22:27.980 回答