免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 12538 | 回复: 9
打印 上一主题 下一主题

socket客户端使用INADDR_ANY,算连接谁? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-20 22:49 |只看该作者 |倒序浏览
10可用积分
写了一个很简单的socket的服务器端,运行在本地,并监听在10080端口。然后作为实验,我写了一个简单的客户端去连它

>cat client.cpp
#include<sys/types.h>
#include<sys/socket.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>//strerror
#include<unistd.h>
#include<arpa/inet.h>
extern int errno;
int main(void){
int s=socket(PF_INET,SOCK_STREAM,0);
if(s==-1){
  printf("socket function failed,%s\n",strerror(errno));
  return 1;
}
sockaddr_in server;
server.sin_family=AF_INET;
server.sin_port  =htons(10080);
server.sin_addr.s_addr=htons(INADDR_ANY);//----------------------------注意这里,我没有使用inet_addr("一个IP"这样的方法
if(connect(s,(sockaddr*)&server, sizeof(server))==-1){
  printf("connect failed,%s\n",strerror(errno));
  return 1;
}
close(s);
return 0;
}

问题:
    上面我的s_addr使用的是实现server端的时候常用的htons(INADDR_ANY),那么这个客户端运行的时候应该去哪台机器呢?
实际上我运行客户端的时候,它连接了我运行在本地10080端口的服务端程序!为什么会这样,难道INADDR_ANY客户端默认连本地?
实在是不能理解啊,还请dx指点,10分感谢!!!!!!!!!!!!!!!附上我的服务器端源代码。我在centOS linux5.2上面
---------------------------------------------------------------------------------------------------------------------------------------------
#include<unistd.h>//read, write, open
#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/un.h>//bzero() function
#include<arpa/inet.h>//sockaddr struct definition
/* This class implements back-end executer
*   The executer will listen for connection at a specific port
*    (specified in wwwconf.txt file)
* then fork a sub-process to communicate with client.
*   The client will send command to this executer and executer returns
* the calling return value of a function or system executable
* or a command line executiion result.
*/
class executer{
public:
    explicit executer(int port);// start executer at the specified port
    ~executer();//end executer
    bool run();
private:
    bool init();
    int iPort;
    int iServerSockFd;// listen on port, accept on this socket.
    bool bInited;
    executer(){};
};

executer::executer(int port){
    iPort=port;
    iServerSockFd=-1;
    bInited=false;
}
executer::~executer(){
    if(iServerSockFd>0)
        close(iServerSockFd);
}
bool executer::init(){
    if(iPort<1 || iPort >65535){
        printf("port number should be between 1-65535";
        return false;
    }
    iServerSockFd=socket(AF_INET,SOCK_STREAM,0);
    if(iServerSockFd==-1){
        printf("executer init failed to set socket\n";
        return false;
    }
    sockaddr_in server;
    server.sin_family=AF_INET;
    server.sin_port  =htons(iPort);
    server.sin_addr.s_addr=htons(INADDR_ANY);
    bzero(&(server.sin_zero), ;
    printf("sockaddr_in.s_addr=%d\n",server.sin_addr.s_addr);
    if(bind(iServerSockFd,
            (sockaddr*)&server,
        sizeof(struct sockaddr))
        ==-1){
        printf("executer init failed to bind socket\n";
        return false;
    }
    if(listen(iServerSockFd,CHILD_MAX)==-1){
        printf("executer init failed to listen on socket\n";
        return false;
    }
    bInited=true;
    return true;
}
bool executer::run(){
    if(bInited==false){
        if(init()==false){
            printf("executer failed to call init()\n";
            return false;
        }
    }
    printf("executer.run()\n";
    while(true){
        sockaddr_in addr;
        socklen_t   size;  
        int client_sock=accept(iServerSockFd,(sockaddr*)&addr,&size);
        if(client_sock==-1){
            printf("executer accept invalid client sock, continue\n";
                continue;
        }else{//fork a process to communicate with client
            printf("executer forks\n";
            int pid=fork();
            if(pid==-1){//failed
                    printf("executer.run() failed to fork\n";
                    continue;
            }else if(pid==0){//father
                    printf("executer fork() successful\n");
            }else{//child
                    //new log file
                    printf("forked sub-process to communicate with client\n");
                    write(client_sock,"221-Bye K.G\r\n",15);
                char buf[200];
                read(client_sock,buf,sizeof(buf));
                printf("buf=%s\n",buf);
                close(client_sock);
            }
        }
    }
}
int main(void){
        executer ect(10080);
        ect.run();
}

最佳答案

查看完整内容

不光是多个网卡的问题.见如下server listen:80 0.0.0.0 //INADDR_ANY,外部的client ask 从哪个server的地址近来都可以连接到80端口.8088 192.168.1.11 //外部的client ask 从server地址192.168.1.11进来才可以连接到8088端口.8089 192.168.1.12 //外部的client ask 从server地址192.168.1.12进来才可以连接到8089端口.也就是说0.0.0.0 是指本地的地址(也就是代表了所有本地的地址,同 ...

论坛徽章:
0
2 [报告]
发表于 2009-03-20 22:49 |只看该作者
原帖由 wxjeacen 于 2009-3-21 12:14 发表
恕我鲁莽,楼上几位纯粹在扯淡。

linux下的socket INADDR_ANY表示的是一个服务器上所有的网卡(服务器可能不止一个网卡)

多个本地ip地址都进行绑定端口号,进行侦听。


不光是多个网卡的问题.

见如下server listen:

80           0.0.0.0               //INADDR_ANY,外部的client ask 从哪个server的地址近来都可以连接到80端口.
8088       192.168.1.11     //外部的client ask 从server地址192.168.1.11进来才可以连接到8088端口.
8089       192.168.1.12     //外部的client ask 从server地址192.168.1.12进来才可以连接到8089端口.

也就是说0.0.0.0 是指本地的地址(也就是代表了所有本地的地址,同一个网卡上也可能有多个地址).
这点上linux,windows系统都是相同的.

而对于在connect中指定了INADDR_ANY,那么:
  1. 在语义上一定是连接到本地地址,不可能是外部地址.
  2. INADDR_ANY在语义上有可能是对应了几个本地地址,因此有的系统会根据缺省规则连接本地指定的服务,而有的系统则因为不能确定用户的任意本地地址是哪个而不能有效连接(如linux和windows不同).

论坛徽章:
0
3 [报告]
发表于 2009-03-20 22:58 |只看该作者
INADDR_ANY 代表了本地任何地址.  一般指: 0.0.0.0
你把client放在另外一台机器上run一下就知道了.

论坛徽章:
0
4 [报告]
发表于 2009-03-20 23:03 |只看该作者

回复 #2 system888net 的帖子

因此server.sin_addr.s_addr=htons(INADDR_ANY) 是connect 自己的本机而已!

论坛徽章:
0
5 [报告]
发表于 2009-03-20 23:24 |只看该作者
更不能理解的是在windows下这样连接居然不行

论坛徽章:
0
6 [报告]
发表于 2009-03-21 12:14 |只看该作者
恕我鲁莽,楼上几位纯粹在扯淡。

linux下的socket INADDR_ANY表示的是一个服务器上所有的网卡(服务器可能不止一个网卡)

多个本地ip地址都进行绑定端口号,进行侦听。

评分

参与人数 1可用积分 +2 收起 理由
jeanlove + 2

查看全部评分

论坛徽章:
0
7 [报告]
发表于 2009-03-21 14:11 |只看该作者
LS的可以试一下,客户端用INADDR_ANY确实可以连上服务器的

不过在windows 下不行

评分

参与人数 1可用积分 +2 收起 理由
jeanlove + 2 我很赞同

查看全部评分

论坛徽章:
0
8 [报告]
发表于 2009-03-23 21:59 |只看该作者
0.0.0.0是表示本地地址啊,不是扯谈啊,0.0.0.0如果为目的地址的话,就是发往本地网卡

论坛徽章:
0
9 [报告]
发表于 2009-03-24 10:30 |只看该作者

回复 #7 cuitoldfish 的帖子

0.0.0.0不是本地地址,你可以ping一下,然后看看你的路由表,它走你的默认网关
当然,它也是发到所谓的“本地网卡”的,呵呵

论坛徽章:
0
10 [报告]
发表于 2009-03-24 10:57 |只看该作者
INADDR_ANY 的值是0.0.0.0,但是平台对它们的处理可能会有不同撒
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP