天天看点

关于socket bind的理解

使用<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

继续阅读