专门为难unix下网络C高手,之如何从系统创建的udp套接字中获得系统产生的随机udp端口

jamesontan 2008-11-10 04:29:55
solaris 10下:
....
struct sockaddr_in Serversin; /* 初始化一个保存应用目标端UDP地址和端口的UDP套接字结构 */
memset((void *)&Serversin, 0, sizeof(struct sockaddr_in));
Serversin.sin_family = AF_INET;
Serversin.sin_addr.s_addr = inet_addr("192.168.1.99");
Serversin.sin_addr..sin_port = htons(8000);

if((ServerUdpSock = socket(AF_INET, SOCK_DGRAM, 0)) <= 0) return 0;/* 创建UDP套接字描述符 */
if(sendto(ServerUdpSock,buf,nread,0,(struct sockaddr *)&Serversin, sizeof(Serversin)) > 0)
printf(" Send UDP data to target success !!\n);
else
printf(" Send UDP data to target success !!\n);

....
请问高手们,如何在成功创建udp套接字ServerUdpSock 并且使用该套接字成功发送buf里的数据之后,在程序里通过该ServerUdpSock UDP套接字获得系统产生的UDP的发送端口?
(上述代码是完全可以正常执行的)
...全文
208 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
herman~~ 2008-11-15
  • 打赏
  • 举报
回复
iSock = (int)socket(AF_INET, SOCK_DGRAM, 0);
if(iSock< 0) { return false; }
if( bind(iSock, (struct sockaddr *)&stiMainAddr,
sizeof(stiMainAddr)) < 0 )
{
return false;
}
//获取真正绑定的本地port
int iGetSockName=sizeof(stiMainAddr);
getsockname(iSock,(struct sockaddr *)&stiMainAddr,
&iGetSockName);
iLoPort=ntohs(stiMainAddr.sin_port);

大概就这样吧,如果不对,丢砖吧
Arthur_ 2008-11-10
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 jamesontan 的回复:]
引用 5 楼 Arthur_ 的回复:
是啊, 调用socket后只是创建一个struct socket和struct sock结构以及产生一个文件描述符和sock->ops(就是send、recv)关联, 其实getsockname在内核的实现是inet_getname你可以google:lxr inet_getname大概可以了解下。

bind 、connect(这里说udp)的其实就是对stuct sock这个结构一些数据初始化,如果没有这步这个数据结构里面是空的,所以你getsockname 啥都没有。

>那么将在第一次调用sen…
[/Quote]

不会的。
jamesontan 2008-11-10
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 Arthur_ 的回复:]
是啊, 调用socket后只是创建一个struct socket和struct sock结构以及产生一个文件描述符和sock->ops(就是send、recv)关联, 其实getsockname在内核的实现是inet_getname你可以google:lxr inet_getname大概可以了解下。

bind 、connect(这里说udp)的其实就是对stuct sock这个结构一些数据初始化,如果没有这步这个数据结构里面是空的,所以你getsockname 啥都没有。

>那么将在第一次调用sendto时指定IP地址和临时端口,其中端口是不会改变的,但是IP地址可能发生改变(受到路由的影>响,可能选择不同的路径发送数据)。一句话,2次sendto的源IP地址可能是不一样的。
当发送sport是0的时候确实会调用get_port产生为它产生一个端口,然后把这个值放到最开始初始化的结构上。
对于ip却不会保存,它取自route cache中的条目, 如果route cache中的条目变化ip 自然变化。

To ls, 你做的实验很正确啊。[/Quote]

hoho,又看到Arthur_ ,每次问题快要解决的时候你才出现。不过看到你还是很高兴哈,你分析的很透彻。
对该socket两次或者多次sendto或者recvfrom,该套接字对应的端口会变化吗?
Arthur_ 2008-11-10
  • 打赏
  • 举报
回复
不会
jamesontan 2008-11-10
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 liuhaoran 的回复:]
.....以前没有想过这个问题,呵呵,,,查了下资料:

不管是UDP还是TCP,在调用socket函数获得描述符之后,IP地址和端口都是未知的,这个时候是无法通过getsockname获得这些信息的,取得的IP地址应该是任意的(即0.0.0.0)。如果此时通过bind绑定了端口,端口就确定下来了,绑定端口的同时可以指定任意IP地址(即0.0.0.0),也可以同时指定一个确定的IP地址,那么该socket的地址也是确定的。
不管是UDP还是TCP,在调用socket函数…
[/Quote]

呵呵,分析的很到位!
一句话,2次sendto的源IP地址可能是不一样的。
那2次sendto源端口会变化吗?
星羽 2008-11-10
  • 打赏
  • 举报
回复
up
Arthur_ 2008-11-10
  • 打赏
  • 举报
回复
>不管是UDP还是TCP,在调用socket函数获得描述符之后,
>IP地址和端口都是未知的,这个时候是无法通过getsockname>
>获得这些信息的,取得的IP地址应该是任意的(即0.0.0.0)
是啊, 调用socket后只是创建一个struct socket和struct sock结构以及产生一个文件描述符和sock->ops(就是send、recv)关联, 其实getsockname在内核的实现是inet_getname你可以google:lxr inet_getname大概可以了解下。

bind 、connect(这里说udp)的其实就是对stuct sock这个结构一些数据初始化,如果没有这步这个数据结构里面是空的,所以你getsockname 啥都没有。

>那么将在第一次调用sendto时指定IP地址和临时端口,其中端口是不会改变的,但是IP地址可能发生改变(受到路由的影>响,可能选择不同的路径发送数据)。一句话,2次sendto的源IP地址可能是不一样的。
当发送sport是0的时候确实会调用get_port产生为它产生一个端口,然后把这个值放到最开始初始化的结构上。
对于ip却不会保存,它取自route cache中的条目, 如果route cache中的条目变化ip 自然变化。

To ls, 你做的实验很正确啊。
liuhaoran 2008-11-10
  • 打赏
  • 举报
回复
.....以前没有想过这个问题,呵呵,,,查了下资料:

不管是UDP还是TCP,在调用socket函数获得描述符之后,IP地址和端口都是未知的,这个时候是无法通过getsockname获得这些信息的,取得的IP地址应该是任意的(即0.0.0.0)。如果此时通过bind绑定了端口,端口就确定下来了,绑定端口的同时可以指定任意IP地址(即0.0.0.0),也可以同时指定一个确定的IP地址,那么该socket的地址也是确定的。
不管是UDP还是TCP,在调用socket函数获得描述符之后,都可以马上调用connect函数,这样内核将为该socket指定一个合适的IP地址和临时端口。并且不会改变。
如果UDP没有调用bind或者connect函数,那么将在第一次调用sendto时指定IP地址和临时端口,其中端口是不会改变的,但是IP地址可能发生改变(受到路由的影响,可能选择不同的路径发送数据)。一句话,2次sendto的源IP地址可能是不一样的。在SERVER端看来就好象是2台不同的主机发来的,只不过端口是一样的。


因为你这里没有bind, connect等,所以getsockname我测试时候用在sendto之后再获取的,做了下实验,得到个端口,但可能因为上面最后一段话,只能获取到端口,你做下实验测试,,,放在sendto后面
dbkcpp 2008-11-10
  • 打赏
  • 举报
回复
getsockname 函数可以实现你的要求
帅得不敢出门 2008-11-10
  • 打赏
  • 举报
回复
帮顶
pingzi_1119 2008-11-10
  • 打赏
  • 举报
回复
楼主的问题比教深奥
不懂
帮顶~

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧