免费注册 查看新帖 |

Chinaunix

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

套接字编程 怎样随机得到一个没有被使用过的端口啊 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-03-30 19:56 |只看该作者 |倒序浏览
好烦啊XXXX
socket编程我崩溃了

论坛徽章:
0
2 [报告]
发表于 2010-03-30 20:41 |只看该作者
开玩笑!你随机取一个端口,别人怎么连上来啊?!

论坛徽章:
0
3 [报告]
发表于 2010-03-31 08:18 |只看该作者
{:3_190:}

论坛徽章:
0
4 [报告]
发表于 2010-03-31 10:49 |只看该作者
我估计楼主没搞清楚,server端,listen的端口就是一直用于listen的。实际与客户端连接传递数据的端口是系统自动随机选择的,不用楼主操心。

论坛徽章:
0
5 [报告]
发表于 2010-03-31 11:52 |只看该作者
如果楼主确实有此需要 , 可以参考 vsftpd-2.0.5 中 postlogin.c 的 handle_pasv() 函数 .
主要部分我把它摘录如下:

  1. while (--bind_retries)
  2.   {
  3.     int retval;
  4.     double scaled_port;
  5.     /* IPPORT_RESERVED */
  6.     unsigned short min_port = 1024;
  7.     unsigned short max_port = 65535;
  8.     if (tunable_pasv_min_port > min_port && tunable_pasv_min_port <= max_port)
  9.     {
  10.       min_port = tunable_pasv_min_port;
  11.     }
  12.     if (tunable_pasv_max_port >= min_port && tunable_pasv_max_port < max_port)
  13.     {
  14.       max_port = tunable_pasv_max_port;
  15.     }
  16.     the_port = vsf_sysutil_get_random_byte();
  17.     the_port <<= 8;
  18.     the_port |= vsf_sysutil_get_random_byte();
  19.     scaled_port = (double) min_port;
  20.     scaled_port += ((double) the_port / (double) 65536) *
  21.                    ((double) max_port - min_port + 1);
  22.     the_port = (unsigned short) scaled_port;
  23.     vsf_sysutil_sockaddr_clone(&s_p_sockaddr, p_sess->p_local_addr);
  24.     vsf_sysutil_sockaddr_set_port(s_p_sockaddr, the_port);
  25.     retval = vsf_sysutil_bind(p_sess->pasv_listen_fd, s_p_sockaddr);
  26.     if (!vsf_sysutil_retval_is_error(retval))
  27.     {
  28.       break;
  29.     }
  30.     if (vsf_sysutil_get_error() == kVSFSysUtilErrADDRINUSE)
  31.     {
  32.       continue;
  33.     }
  34.     die("vsf_sysutil_bind");
  35.   }
  36.   if (!bind_retries)
  37.   {
  38.     die("vsf_sysutil_bind");
  39.   }
  40.   vsf_sysutil_listen(p_sess->pasv_listen_fd, 1);
  41.   if (is_epsv)
  42.   {
  43.     str_alloc_text(&s_pasv_res_str, "Entering Extended Passive Mode (|||");
  44.     str_append_ulong(&s_pasv_res_str, (unsigned long) the_port);
  45.     str_append_text(&s_pasv_res_str, "|)");
  46.     vsf_cmdio_write_str(p_sess, FTP_EPSVOK, &s_pasv_res_str);
  47.     return;
  48.   }
复制代码

论坛徽章:
0
6 [报告]
发表于 2010-03-31 22:40 |只看该作者
谢谢大家啊
我的目的主要是建立一个p2p类似的共享传输网络
然后用udp连接的时候随机选取一个端口与另一台机器连接

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
7 [报告]
发表于 2010-04-01 00:41 |只看该作者

  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. #include <netinet/in.h>
  4. #include <arpa/inet.h>
  5. #include <errno.h>
  6. #include <string.h>
  7. int my_random_bind(int* pfd,unsigned short*pport)
  8. {
  9.         static int x=0;
  10.         int fd;
  11.         unsigned short port,tmp;
  12.         struct sockaddr_in  addr;
  13.         if(x == 0) {
  14.                 srand((unsigned)time(NULL));
  15.                 x = 1;
  16.         }
  17.         tmp=port=rand()%(0x10000-1024)+1024;
  18.         while(port!=0xffff) {
  19.                 fd = socket(AF_INET, SOCK_DGRAM, 0);
  20.                 if(fd<0)
  21.                         return -1;

  22.                 memset(&addr,0,sizeof(addr));
  23.                 addr.sin_addr.s_addr = htonl(INADDR_ANY);
  24.                 addr.sin_family = AF_INET;
  25.                 addr.sin_port = htons(port);

  26.                 if(bind(fd,(struct sockaddr *)&addr, sizeof(struct sockaddr_in))<0) {
  27.                         if(errno == EADDRINUSE) {
  28.                                 close(fd);
  29.                                 port++;
  30.                         } else {
  31.                                 close(fd);
  32.                                 return -1;
  33.                         }
  34.                 } else {
  35.                         *pfd=fd;
  36.                         *pport=port;
  37.                         return 0;
  38.                 }
  39.         }
  40.         port=tmp-1;
  41.         while(port!=1024) {
  42.                 fd = socket(AF_INET, SOCK_DGRAM, 0);
  43.                 if(fd<0)
  44.                         return -1;

  45.                 memset(&addr,0,sizeof(addr));
  46.                 addr.sin_addr.s_addr = htonl(INADDR_ANY);
  47.                 addr.sin_family = AF_INET;
  48.                 addr.sin_port = htons(port);

  49.                 if(bind(fd,(struct sockaddr *)&addr, sizeof(struct sockaddr_in))<0) {
  50.                         if(errno == EADDRINUSE) {
  51.                                 close(fd);
  52.                                 port--;
  53.                         } else {
  54.                                 close(fd);
  55.                                 return -1;
  56.                         }
  57.                 } else {
  58.                         *pfd=fd;
  59.                         *pport=port;
  60.                         return 0;
  61.                 }
  62.         }
  63.         return -2;

  64. }

复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP