使用<code>bind</code>函数绑定ip和端口时有如下几种可能:
ip地址
端口
结果
通配地址
内核选择ip地址和端口
非0
内核选择ip地址,进程指定端口
本地ip地址
进程指定ip地址,内核选择端口
进程指定ip地址和端口
使用规则:
服务器进程一般在启动时都会<code>bind</code>某个端口(例如 http的80端口),而客户端进程都不会指定端口。若未调用<code>bind</code>接口,则内核会为其指定一个临时端口。
服务端进程也有不指定端口的case,比如rpc服务。服务端进程在<code>listen</code>后向 <code>rpc服务注册进程</code> 注册自己的地址和端口。rpc客户端只需要向 <code>rpc服务注册进程</code> 请求对应的服务,即可返回rpc服务的ip和port信息。
若指定ip地址,则该ip地址必须是属于其主机的网络接口之一(<code>127.0.0.1</code>,网卡eth0地址 <code>192.168.0.102</code>,其他网卡地址)。
对于tcp客户端来说,其指定发送ip数据报的源地址 对于tcp服务端来说,其限定了该socket只接收目的地址为该ip的connect请求。
若tcp服务端不指定ip,内核会把客户端发送的syn的目的地址作为服务端的源地址(该connect socket的源地址)
注:一个listen socket可以accept多个socket连接,accept返回的connect socket的源地址可能为<code>127.0.0.1</code>,<code>192.168.0.102</code>,或者其他本机ip
下面用代码证实下:
一般,启动服务器监听的代码如下:
启动绑定在通配ip和1234端口的服务端程序
使用 <code>telnet 127.0.0.1 1234</code>命令连接服务端
服务端显示
connect from 127.0.0.1, port:58271 sock name 127.0.0.1, port:1234
peer sock name 127.0.0.1, port:58271
使用 <code>telnet 192.168.0.102 1234</code> 连接服务端
connect from 192.168.0.102, port:58282 sock name 192.168.0.102, port:1234
peer sock name 192.168.0.102, port:58282
反注释以下代码,启动服务端程序
客户端显示
telnet: connect to address 192.168.0.102: Connection refused telnet: Unable to connect to remote host
注:telnet 操作相当于connect指定了服务端的ip和port