LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1772|回复: 13

UDP的socket绑定到IP地址后无法接受广播数据

[复制链接]
发表于 2005-11-10 18:37:30 | 显示全部楼层 |阅读模式
由于考虑到我的程序要在多网卡的机器上运行,所以我将网卡的ip地址绑定到了socket
server_addr.sin_addr.s_addr = inet_addr(servIP);但是这样就无法收到广播数据?同时我也绑定到了一个广播地址接受时发现没次客户端来的数据都连续接受两次;请问是为什么?

以下是我的测试程序:

//server.cpp
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>

char * host_name = "192.168.0.255";
int port = 10051;

int main(void)
{
        struct sockaddr_in serv_addr,addr;
        char buf[256];
        
        int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sockfd == -1)
        {
                perror("Error: socket";
                return -1;
        }
        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = inet_addr(host_name);//htonl(INADDR_ANY);//
   
        int bd = bind(sockfd,  (struct sockaddr*)&addr, sizeof(struct sockaddr_in));
        while(1)
        {
                int len = sizeof(serv_addr);
                memset(&serv_addr, 0, len);
                int ret = recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&serv_addr,(socklen_t*)&len);
                printf("recv=%d buf=%s
",ret, buf);
                printf("RecvieIP:%s  Recive Port:%d
", inet_ntoa(serv_addr.sin_addr),
                                ntohs(serv_addr.sin_port));
                ret = sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr_in));
        }        
        
}


//client.cpp

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>

char * host_name = "192.168.0.255";

int port = 10051;
int main(void)
{
        int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sockfd == -1)
        {
                perror("Error: socket";
                return -1;
        }
        
        struct sockaddr_in serv_addr;
        memset(&serv_addr, 0, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(port);
        serv_addr.sin_addr.s_addr = inet_addr(host_name);
    int so_broadcast;
        setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &so_broadcast,
                sizeof(so_broadcast));

        char buf[256]="client .............";
        sockaddr from ;
        int len;
        sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr_in));
    while(1)
    {
            recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&serv_addr,(socklen_t*)&len);
                printf("server buf= %s
",buf);
        }
}
发表于 2005-11-10 21:12:16 | 显示全部楼层
你给你的server帮定一个广播地址叫它怎么接受数据!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-11-10 21:26:59 | 显示全部楼层
Post by haohao_h
你给你的server帮定一个广播地址叫它怎么接受数据!


因为我要接受广播数据如果绑定道指定的ip地址,就无法收到客户端发来的数据,我现在绑定广播地址后每次都要收到两次相同的数据.我的两个ip地址分别是192.168.0.2 和196.168.0.172.
回复 支持 反对

使用道具 举报

发表于 2005-11-11 08:42:32 | 显示全部楼层
Post by fannyth
因为我要接受广播数据如果绑定道指定的ip地址,就无法收到客户端发来的数据,我现在绑定广播地址后每次都要收到两次相同的数据.我的两个ip地址分别是192.168.0.2 和196.168.0.172.

推荐你看一本书,richard stevens的unix 网络编程卷一
回复 支持 反对

使用道具 举报

发表于 2005-11-11 11:10:53 | 显示全部楼层
双网卡最好不要设成一个网段

你两块网卡一个网段,结果两个网卡都收到广播数据
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-11-11 11:20:11 | 显示全部楼层
Post by x11
双网卡最好不要设成一个网段

你两块网卡一个网段,结果两个网卡都收到广播数据


是的,但是程序给别人用的时候很难保证别人机器的双网卡是否在一个网段内。我想知道的是如果将socket绑定到指定的地址后是否就无法接受广播包了。
回复 支持 反对

使用道具 举报

发表于 2005-11-11 12:01:53 | 显示全部楼层
应该不会
int so_broadcast =1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &so_broadcast, sizeof(so_broadcast));
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-11-11 12:15:52 | 显示全部楼层
Post by x11
应该不会
int so_broadcast =1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &so_broadcast, sizeof(so_broadcast));


我试过了,我在接受端将socket绑定到了一个ip地址,同时在接受端我也加了这句,但还是收不到广播包
回复 支持 反对

使用道具 举报

发表于 2005-11-11 12:36:03 | 显示全部楼层
嗯,bind到网卡地址是不能接收广播包的

那你就别bind了呗
回复 支持 反对

使用道具 举报

发表于 2005-11-11 12:48:29 | 显示全部楼层
Post by x11
嗯,bind到网卡地址是不能接收广播包的

那你就别bind了呗


udp广播的递送规则是:
如果没有设置BLOADCASE选项的不递送。
如果bind端口不匹配不递送该套接口
如果绑定的不是INADDR_ANY话
那么必须BIND的地址和目的地址匹配才能递送:
也就是说你必须BIND一个广播地址或者绑定INADDR_ANY
第三
如果你的udp调用了connect
那么源地址和源端口不匹配也不递送
否则递送

你可以设置其中一个网卡DISABLE广播能力
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表