怎样在socket代码中获得由内核自动分配的端口号

来源:互联网 发布:easyui tree加载数据 编辑:程序博客网 时间:2024/05/21 09:31

http://bbs.chinaunix.net/thread-1460809-2-1.html


请教一个问题,我正在写一个linuxftp客户端程序,遇到一个问题,请各位大侠帮助。


根据ftp协议,客户端将会通过port命令将客户端建立的一个监听端口发给ftp服务器,然后ftp服务器将connect到该端口上,如果在客户端程序中强制设置一个端口,当然可以,但是我希望由内核自动分配一个可用端口。我们知道通常设置sockaddr_in的sin_port字段为0,就是告诉内核自己分配,但是这样在客户端代码中就无法正确得到这个端口值了,因为客户端代码中总是0,谁能提醒下俺呢? 谢谢!


getsockname()

getsockname函数不行

我已经试过getsockname函数,该函数返回的端口仍然是0(printf函数中返回的值仍然是0),如下代码所示:
---------------------------------------------------------------------------------------
155           memset (&local_addr, 0, sizeof local_addr);
156           local_addr.sin_family = AF_INET;
157           local_addr.sin_addr.s_addr = htonl (INADDR_ANY);
158           local_addr.sin_port = 0;
159
160           /* bind client's passive process to server listening socket */
161           if ((bind
162            (sockfd_data, (struct sockaddr *) (&local_addr),
163             sizeof local_addr)) == -1)
164         {
165           fprintf (stderr, "Bind error: %s\a\n", strerror (errno));
166           exit (1);
167         }
168
169           /* concat port to parm */
170           getsockname(sockfd_data, (struct sockaddr*)&local_addr, &sin_size);
171           port=ntohs(local_addr.sin_port);
172
173           printf("in child process port is: %d\n", port);

你是bind() listen()之后么

就是bind后,没有在listen后面,我想的是一旦绑定后,子进程就通知父进程已获得一个端口号,于是父进程就可以开始发送port命令了

我这里的strace结果
  1. bind(7, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("xxxxxx")}, 16) = 0
  2. listen(7, 128)                          = 0
  3. getsockname(7, {sa_family=AF_INET, sin_port=htons(31415), sin_addr=inet_addr("xxxxx")}, [16]) = 0
复制代码


我将代码移到listen后,printf打出的结果仍然为0呢?郁闷
---------------------------------------------------------------

172           if (listen (sockfd_data, 5))
  173         {
  174           fprintf (stderr, "Listen error: %s\n\a", strerror (errno));
  175           exit (1);
  176         }
  177
  178           getsockname(sockfd_data, (struct sockaddr*)&local_addr, &sin_size);
  179           port=ntohs(local_addr.sin_port);
  180
  181           printf("in child process port is: %d\n", port);

我发现一个问题,如果是单独的一个程序通过getsockname可以得到内核分配的端口,但是在我这个多进程的ftp客户端中就始终得不到

sin_size赋值了么?

果然,我忘了赋值了,我的赋值刚好在getsockname的后面。

非常感谢风行者!

原创粉丝点击