LinuxSir.cn,穿越时空的Linuxsir!

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

getsockname函数的问题!

[复制链接]
发表于 2007-6-27 17:20:34 | 显示全部楼层 |阅读模式
Linux系统的server,有多个IP地址。写了个程序,想使用getsockname函数得到本地接收信息的IP地址(事先不绑定socket的IP地址)。程序运行后,得到的IP总是:0.0.0.0而不是实际的接收信息的IP地址。这是怎么回事呢?怎样才能得到实际的接收信息的ip地址呢?程序如下:
---------------------
这是服务器端的程序,另外还有一个客户端定时向server发送信息。
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
int main()
{
        int sock;
        char buff[100];
        socklen_t  i;
        char *p;
        int pport;
        struct sockaddr_in address,ad;
        address.sin_family=AF_INET;
        address.sin_port=htons(5678);
        address.sin_addr.s_addr=htonl(INADDR_ANY);
        sock=socket(AF_INET,SOCK_DGRAM,0);
        ad.sin_family=AF_INET;
        ad.sin_addr.s_addr=htonl(INADDR_ANY);
        bind(sock,(struct sockaddr *)&address,sizeof(address));
        memset(buff,0,100);
        i = sizeof(struct sockaddr_in);
        recvfrom(sock,buff,100,0,(struct sockaddr *)&source,&i);
        printf("Data recieved is:%s\n",buff);
        i = sizeof(struct sockaddr_in);
        if(getsockname(sock,(struct sockaddr *)&ad,&i))
        {
                puts("Error!");
        }
        p=inet_ntoa(ad.sin_addr.s_addr);
        printf("Ip is:%s\n",p);
        close(sock);
}
发表于 2007-6-27 19:06:04 | 显示全部楼层
在/usr/include/netinet/in.h里有这样一个宏定义:
[PHP]
    #define INADDR_ANY   (u_long)0x00000000
[/PHP]
在就是说,INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。
回复 支持 反对

使用道具 举报

发表于 2007-6-27 19:08:14 | 显示全部楼层
另外希望楼主以后贴代码的时候最好用[code]括起来,这样别人也好帮你调试
回复 支持 反对

使用道具 举报

发表于 2007-6-30 18:38:57 | 显示全部楼层
你这样得到的源地址肯定还是INADDR_ANY,你所创建的套接字是SOCK_DGRAM类型的套接字,并且绑定的本地地址是通用地址INADDR_ANY,也就意味着发送方只要指定的目的地址是广播地址、你主机上任一ip地址,都会被该socket所接收,所以对于没有SOCK_DGRAM类型的socket,如果你绑定时候没有指定本地地址,那么这个socket本地地址永远是零,这同SOCK_STREAM类型的socket是不同的,SOCK_STREAM类型的套接字是流体面向连接的,例如TCP,当你创建一个tcp套接字,如果你绑定时候不指定本地地址,那么当你发送数据报的时候,网络内核协议栈会根据数据报的目的地址,来判断网络出口,从而由系统为该tcp套接字绑定网络出口的ip地址,所以对于tcp,你可以通过getsockname来获得socket的本地地址(即时你bind时候用INADDR_ANY),但是SOCK_DGRAM就不行了例如udp。
回复 支持 反对

使用道具 举报

发表于 2007-6-30 18:39:11 | 显示全部楼层
你这样得到的源地址肯定还是INADDR_ANY,你所创建的套接字是SOCK_DGRAM类型的套接字,并且绑定的本地地址是通用地址INADDR_ANY,也就意味着发送方只要指定的目的地址是广播地址、你主机上任一ip地址,都会被该socket所接收,所以对于没有SOCK_DGRAM类型的socket,如果你绑定时候没有指定本地地址,那么这个socket本地地址永远是零,这同SOCK_STREAM类型的socket是不同的,SOCK_STREAM类型的套接字是流体面向连接的,例如TCP,当你创建一个tcp套接字,如果你绑定时候不指定本地地址,那么当你发送数据报的时候,网络内核协议栈会根据数据报的目的地址,来判断网络出口,从而由系统为该tcp套接字绑定网络出口的ip地址,所以对于tcp,你可以通过getsockname来获得socket的本地地址(即时你bind时候用INADDR_ANY),但是SOCK_DGRAM就不行了例如udp。
回复 支持 反对

使用道具 举报

发表于 2007-6-30 18:39:13 | 显示全部楼层
你这样得到的源地址肯定还是INADDR_ANY,你所创建的套接字是SOCK_DGRAM类型的套接字,并且绑定的本地地址是通用地址INADDR_ANY,也就意味着发送方只要指定的目的地址是广播地址、你主机上任一ip地址,都会被该socket所接收,所以对于没有SOCK_DGRAM类型的socket,如果你绑定时候没有指定本地地址,那么这个socket本地地址永远是零,这同SOCK_STREAM类型的socket是不同的,SOCK_STREAM类型的套接字是流体面向连接的,例如TCP,当你创建一个tcp套接字,如果你绑定时候不指定本地地址,那么当你发送数据报的时候,网络内核协议栈会根据数据报的目的地址,来判断网络出口,从而由系统为该tcp套接字绑定网络出口的ip地址,所以对于tcp,你可以通过getsockname来获得socket的本地地址(即时你bind时候用INADDR_ANY),但是SOCK_DGRAM就不行了例如udp。
回复 支持 反对

使用道具 举报

发表于 2007-6-30 18:42:01 | 显示全部楼层
UDP在每个套接字的接收缓冲区对应的每个接收数据报,都有记录该数据报的源地址、端口和目的地址、端口。getsockname只是获得socket中的源地址、端口。
回复 支持 反对

使用道具 举报

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

本版积分规则

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