多播绑定 - 已在使用的地址

时间:2012-10-04 19:19:32

标签: c linux bind multicast

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

错误消息是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....

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

在一个进程的同一个host:port上可以有多个打开的套接字,不可能有多个进程要监听(即绑定)到同一个host:port

也许,您之前的服务器流程实例尚未实现。

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