一个多socket绑定同一个端口的测试程序

 

测试目标:建立多个socket的测试

 

测试环境:suse Linux

 

测试步骤:建立了3个socket,但是由于绑定了不同的端口,可以邦定成功;假如绑定相同的端口,则相继失败。而关闭socket的时候,调用shutdown失败,而close却可以成功。

在stevens的书本中,则建议使用shutdown来关闭,但是,不成功。

 

测试结果:

goal: test multi socket could be binded in the same port
creating socket:
socket is created: 3
socket is created: 4
socket is created: 5


current pid: %d
18116


bind socket:

binding the 8000 port
binding the 8001 port
binding the 8002 port


shut down  the socket
shut down socket 1 error
shut down socket 2 error
shut down socket 333 error

疑问:

1、为什么一个程序不同的socket不可以邦定同一个端口呢?

2、为什么shutdown失败?而close则可以成功呢?

3、为什么多个进程里面,每个进程都有一个socket,多个进程绑定的却是同一个端口,还是失败呢?

 

测试源代码:

 

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <sys/time.h>
  5. #include <sys/types.h>
  6. #include <string.h>
  7. #include <signal.h>
  8. #include <sys/socket.h>
  9. #include <netinet/in.h>
  10. #include <arpa/inet.h>
  11. #include <errno.h>
  12. #include <unistd.h>
  13. #include <iostream>
  14. using namespace std;
  15. int bind_socket(int sock, int port);
  16. int create_socket();
  17. int main(int argc, char** argv)
  18. {
  19.     std::cout << "goal: test multi socket could be binded in the same port" << endl;
  20.     
  21.     int socket_1, socket_2, socket_3;
  22.     int port_1 = 8000, port_2 = 8001, port_3 = 8002;
  23.     std::cout << "creating socket:" << endl;    
  24.     socket_1 = create_socket();
  25.     std::cout << "socket is created: " << socket_1 << endl;
  26.     
  27.     socket_2 = create_socket();
  28.     std::cout << "socket is created: " << socket_2 << endl;
  29.          
  30.     socket_3 = create_socket();
  31.     std::cout << "socket is created: " << socket_3 << endl;
  32.     std::cout << "/n/ncurrent pid: " << getpid() << endl;
  33.     std::cout << "/n/nbind socket:/n" << endl;
  34.     std::cout << "binding the " << port_1 << " port" << endl;
  35.     if(bind_socket(socket_1, port_1) == -1 )
  36.     {
  37.         std::cout << "bind socket 1 error" << endl;    
  38.     }
  39.     
  40.     std::cout << "binding the " << port_2 << " port" << endl;
  41.     if(bind_socket(socket_2, port_2) == -1 )
  42.     {
  43.         std::cout << "bind socket 2 error" << endl;    
  44.     }
  45.     
  46.     std::cout << "binding the " << port_3 << " port" << endl;
  47.     if(bind_socket(socket_3, port_3) == -1 )
  48.     {
  49.         std::cout << "bind socket 3 error" << endl; 
  50.     }
  51.     std::cout << "/n/nshut down  the socket" << endl;
  52.     if(shutdown(socket_1, SHUT_RDWR) == -1)
  53.     {
  54.         std::cout << "shut down socket 1 error" << endl;
  55.      if(close(socket_1) == -1)
  56.          std::cout << "close socket 1 failed" << endl;
  57.     }
  58.     
  59.     if(shutdown(socket_2, SHUT_RDWR) == -1)
  60.     {
  61.         std::cout << "shut down socket 2 error" << endl;
  62.     }
  63.     
  64.     if(shutdown(socket_3, SHUT_RDWR) == -1)
  65.     {
  66.         std::cout << "shut down socket 333 error" << endl;
  67.     }
  68.     return 1; 
  69. }
  70. int create_socket()
  71. {
  72.     int s;
  73.     
  74.     if((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  75.     {
  76.         std::cout << "create socket failed!" << endl;
  77.         close(s);
  78.         return -1;
  79.     }
  80.     
  81.     return s;
  82. }
  83. int bind_socket(int sock, int port)
  84. {
  85.     struct sockaddr_in addr;
  86.     if(sock <= 0)
  87.     {
  88.         std::cout << "input socket error: " << sock << endl;    
  89.         return -1;
  90.     }
  91.     
  92.     if(port <= 1024)
  93.     {
  94.         std::cout << "intput port error: " << port << endl;
  95.         return -1;    
  96.     }
  97.     
  98.     memset(&addr, 0, sizeof(addr));
  99.     addr.sin_port = htons (port);
  100.     addr.sin_family = AF_INET;
  101.     
  102.     int ret = bind(sock,(struct sockaddr *)&addr, sizeof(addr));
  103.     if( ret < 0) 
  104.     {
  105.         std::cout << "bind error: " << ret << endl;
  106.         close(sock);
  107.      std::cout << "close socket: " << sock << endl;
  108.         return -1;
  109.     }
  110.     
  111.     return ret;   
  112. }

结果分析:

问题1:同事告诉我可以的,结果证明不行。说明Ericsson的TSP的强大性,哈哈

问题2:看来就用close吧。在TSP封装后的接口中,使用的是close而不是shutdown,在通用程序中,也是使用close居多。而两者的最大区别就是socket descriptor dup之后的差别,也就是说,不把socket descriptor dup的话,两者效果一样。

问题3:我使用的测试程序是:启动程序,然后fork两个进程,每个都建立一个socket,这样3个socket都绑定到了同一个端口,结果失败。因此,并不是每个进程都可以侦听同一个端口的。这样一说,也不难理解啦。

 

欢迎拍砖!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值