免费注册 查看新帖 |

Chinaunix

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

求救,邦定端口失败 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-08-22 10:47 |只看该作者 |倒序浏览
如果进程邦定指定的端口号来建立一个监听套接字以后,且监听套接字接受过请求,并生成若干已连接套接字。
在同一个进程中,我想在这时候用前述的监听套接字邦定的端口来建立另外一个套接字,去连接其他监听套接字。我的这次邦定好像不能成功,我应该怎么做才能够成功的建立这个套接字。

但是如果下面的情况却没有错误发生:
进程邦定指定的端口建立一个套接字去连接一个监听套接字。连接建立了起来。这个时候我使用刚才的那个指定的端口来建立一个监听套接字,bind却是能够正确返回的,且监听套接字可以接受连接。

为什么地一种情况bind不能够正确返回,第二种情况,看起来就只是将第一种的两个套接字的建立的顺序颠倒过来,然后就不可以,这个是为什么?

[ 本帖最后由 ahhhhwang 于 2008-8-22 11:21 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-08-22 15:29 |只看该作者
表达的意思大家估计没怎么看明白哦

论坛徽章:
0
3 [报告]
发表于 2008-08-22 16:57 |只看该作者
抱歉说的不清楚。
第一种情况,首先邦定指定端口给一个tcp客户套接口,然后邦定相同端口给一个tcp监听套接口:
   进程执行下面代码,进程邦定34563建立套接字去连接邦定了20的监听套接口。连接成功后建立一个同样邦定了34563的监听
   套接口,并且在另外一个进程中建立套接字连接这个监听套接字,并且成功成功。
   在这种情况下,重复邦定34563成功了。
    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    ret=1;
    ret=setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&ret,sizeof(int));

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr("127.0.0.1");
    address.sin_port = htons(34563);
    len = sizeof(address);       
    ret=bind(sockfd,(struct sockaddr *)&address,len);

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr("127.0.0.1");
    address.sin_port = htons(20);
    len = sizeof(address);
    result = connect(sockfd, (struct sockaddr *)&address, len);          
///////////////////////////////////////////
    sockfd1 = socket(AF_INET, SOCK_STREAM, 0);
      
    ret=1;
    ret=setsockopt(sockfd1,SOL_SOCKET,SO_REUSEADDR,&ret,sizeof(int));

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr("127.0.0.1");
    address.sin_port = htons(34563);
    len = sizeof(address);       
    ret=bind(sockfd1,(struct sockaddr *)&address,len);

    ret=listen(sockfd1, 5);
      
    ret=accept(sockfd1,NULL,NULL);
      
     exit(0);

第二种情况,首先邦定指定端口给一个tcp监听套接口,然后邦定相同端口给一个tcp客户套接口:
进程执行下面代码,进程邦定20000建立监听套接字,在另外一个进程中建立套接字连接这个监听套接字,并且连接成功。然后建立一个同样邦定了20000的tcp客户套接口,去连接其他监听套接字,但在邦定时候出错了。
在这种情况下,第二次邦定20000失败了。
    server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

    ret=1;
    ret=setsockopt(server_sockfd,SOL_SOCKET,SO_REUSEPORT,&ret,sizeof(int));

    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_address.sin_port = htons(20000);
    server_len = sizeof(server_address);
    ret=bind(server_sockfd, (struct sockaddr *)&server_address, server_len);
   
    ret=listen(server_sockfd, 5);

    ret=accept(server_sockfd,NULL,NULL);

////////////////////////

    int sockfd;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
  
    ret=1;
    ret=setsockopt(sockfd,SOL_SOCKET,SO_REUSEPORT,&ret,sizeof(int));

    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_address.sin_port = htons(20000);
    server_len = sizeof(server_address);
    ret=bind(sockfd, (struct sockaddr *)&server_address, server_len);
  
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr("127.0.0.1");
    address.sin_port = htons(34561);
    len = sizeof(address);
    result = connect(sockfd, (struct sockaddr *)&address, len);

   exit(0);

  比较这两种情况,似乎可以得到下面的结论:如果一个指定的端口号如果首先邦定到一个监听套接口,那么就不能重复邦定到另外的套接字上(不论这个套接字将会是监听套接字或者客户套接字,在bind调用的时候就会错误返回)。但是如果将一个指定的端口号如果首先邦定到一个客户套接口,那么还可以将这个端口号邦定到另外的套接口上。

论坛徽章:
0
4 [报告]
发表于 2008-08-22 17:25 |只看该作者
我想这个原因可能与下面这个原因有关吧。
客户端可以不显示地绑定port,如果没绑定port的话,linux会随机为应用程序选择一个端口.
而服务器必须绑定固定的监听端口。

再你测试成功的那种情况中,也许内核发现这个端口已经被绑定了,就又随机为它选择了一个端口呢。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP