socketbind详解
在最开始接触bind的时候,只是在写基于tcp的server端的时候,知道在listen之前需要先bind⼀下,⽤来确保socket能在某个固定的端⼝监听。⽽bind的时候,函数参数中的端⼝填⾃⼰将要绑定的端⼝就⾏;⽽IP地址,需要填本机的IP,但是也可以⽤⼀个宏INADDR_ANY代替,⽤这个宏就可以不⽤查本机的IP,它就可以代替本机的IP。当时只觉得这个INADDR_ANY⽐较神奇,但是由于当时觉得⽤起来很⽅便,也没出啥问题,也就没有再深究。
但是最近在做RTSP服务器的时候,有种特殊的应⽤,导致我不得不对bind这个函数仔细地看⼀下。
我们知道⽆论是UDP还是TCP,socket都会与⼀个本地的IP和端⼝想对应,我们往往把这个IP和端⼝称之为socket的源地址和源端⼝。当我们作为客户端利⽤socket去发送数据时,很少会去考虑这个源地址和源端⼝到底是什么,我们更关⼼的是它的⽬的地址和端⼝。我们往往只有在监听的时候,才去考虑这个源端⼝,所以我们在监听的时候会去⽤bind。当我们bind之后,内核就会将这个socket的源端⼝锁定到我们设定的端⼝上。但是这就有⼀个问题,这个bind绑定端⼝,是将本来没有源端⼝的socket绑定到我们指定的端⼝上,还是将⼀个已经分配了端⼝的socket重定向到我们指定的端⼝上呢?
在《UNIX⽹络编程》这本书中提到:“如果⼀个TCP客户或者服务器未曾调⽤bind捆绑⼀个端⼝,当调⽤connect或listen时,内核就要为相应的套接字选择⼀个临时接⼝。”从这句话中可以判断出,其实在调⽤so
cket函数创建socket时,内核还并未给socket分配源地址和源端⼝。⽽对于UDP,我猜测在调⽤sendto 发送数据时,在未捆绑端⼝的情况下,内核也会随机分配端⼝。
socket通信为什么要指定端口 ⽽我遇到的特殊应⽤要求我在⽤UDP发送数据之前要告诉对⽅我的发送端⼝,这也就意味着我在sendto之前必须要捆绑端⼝,因此我在发送数据之前就得调⽤bind函数绑定⼀下端⼝了。但是我就在想内核既然有随机分配端⼝的能⼒,⽽我需要的也只是让它绑定⼀下⽽不⽤绑定在固定端⼝的业务,socket中应该能够提供这种业务。然后果然我发现bind就具备这种能⼒,当bind的参数中端⼝地址为0的时候,这时候就是由内核分配端⼝。这样我就不⽤考虑端⼝地址重复的问题,⽽放⼼的把这个问题交给内核处理了。
就在发现bind的这个机制的同时,我发现其实bind对于源地址也同样具备这种处理⽅式,当系统具有多IP(多⽹卡)的情况,当我们把bind函数中的ip参数置0时,就是由内核⾃⼰选择分配IP。⽽之前⼀直觉得很神奇的INADDR_ANY其实⼀点也不神奇,它的值其实就是0。所以当我们只有单⼀IP的时候,我们就可以⽤INADDR_ANY去代替那个单⼀的IP,因为内核分配的时候只能选择这⼀个IP。从⽽造成了INADDR_ANY就是本机IP的现象。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论