文章目录端口一、端口的作用二、端口的取值范围三、端口的分类四、NAT五、端口复用六、端口在消息传递中的应用端口一、端口的作用浅显的认知是端口对应着系统中每个进程一对一的关系。IP是主机的唯一标识它使在纷繁复杂Internet网里能精确定位到某个目的主机。客户端一个请求发出通过IP定位到服务器但是服务器上可能运行着众多进程请求到底该分发给哪个进程IP地址无能为力网络端口孕育而生完美解决这个问题。IP和端口两个相辅相成IP主外端口主内它们总是形影不离。二、端口的取值范围端口在计算机中占用2byte16位无符号总共能表示的数字范围0~216-165535。三、端口的分类著名端口0~1023都属于固定服务使用官方硬性规定的。比如ftp:21,ssh:22,telnet:23,smtp:25,Http:80,https:443,tomcat:8080,oracle:1521,mysql:3306点击查看端口分配监听端口:范围有很多种说法也没有权威的认定。动态端口除了著名端口、监听端口剩下的都是动态端口。四、NAT在当今庞大的网络系统中现有的IP数量完全不够分在IPv6出现之前聪明的人类想出了一个办法那就是NATNetwork Address Translation网络地址转换摘取一段引用在一个典型的配置中一个本地网络使用一个专有网络的指定子网 比如192.168.x.x或10.x.x.x和连在这个网络上的一个路由器。 这个路由器占有这个网络地址空间的一个专有地址比如192.168.0.1 同时它还通过一个或多个因特网服务提供商提供的公有的IP地址叫做“过载”NAT 连接到因特网上。当信息由本地网络向因特网传递时源地址被立即从专有地址转换为公用地址。 由路由器跟踪每个连接上的基本数据主要是目的地址和端口。当有回复返回路由器时 它通过输出阶段记录的连接跟踪数据来决定该转发给内部网的哪个主机 如果有多个公用地址可用当数据包返回时TCP或UDP客户机的端口号可以用来分解数据包。 对于因特网上的一个系统路由器本身充当通信的源和目的地址。五、端口复用不同的进程可以监听在同一个IP地址:端口号么根据Unix网络编程中的知识可知服务端监听一个端口会经历1、根据套接字类型(Ipv4,Ipv6等)创建套接字socket2、将套接字bind绑定到具体的网络地址和端口号3、调用listen开始在这个套接字上进行监听。Unix提供了一个接口setsockopt()可以在bind之前设置套接字选项其中就包括REUSEADDR这个选项表明可以多个进程复用bind函数中指定的地址和端口号。由此可知多个应用(进程)包括同一个应用多次都是可以绑定到同一个端口进行监听的。从一些例子也可以看出比如有时候你在服务器上执行netstat -ano可能会发现同一个应用程序在同一个端口上有多个监听这是因为一些服务端应用程序可能会异常退出或者没有完全释放套接字但是需要在重新启动时还能够再次监听同一个端口所以需要能够具备重复监听同一个端口的能力因此也出现上述情形。SO_REUSEADDR为什么有时候重启Apache会失败报“Address already in use”TCP的原理会导致这样的一个结果主动close socket的一方会进入TIME_WAIT这个状况持续的时间取决于三件事TCP关闭连接的五次挥手包什么时候到达SO_LINGER的设置/proc/sys/net/ipv4/tcp_tw_recycle 和 /proc/sys/net/ipv4/tcp_tw_reuse 的设置总之默认情况下处于TIME_WAIT状态的端口是不能用来LISTEN的。 这就导致Apache重启时产生80端口TIME_WAIT进而导致Apache再次尝试LISTEN失败。在很多开源代码里我们会看到如下代码int reuseaddr 1;setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, reuseaddr, sizeof(int));有了上面这段神奇的代码就不会出现上面的惨剧。但SO_REUSEADDR的作用不仅限于上述Linux 的 SO_REUSEADDR 设置为 1 有四种效果当端口处在TIME_WAIT时候可以复用监听。可以允许多个进程监听同一端口但是必须不同IP。这里说的比较隐晦如果进程A监听0.0.0.0:80B进程可以成功监听127.0.0.1:80 顺序反过来也是可以的。允许单个进程绑定相同的端口到多个socket上但每个socket绑定的IP地址不同。使用UDP时候可以允许多个实例或者单进程同时监听同个端口同个IP。六、端口在消息传递中的应用在TCP/IP协议中用“源IP地址”“目的IP地址”“源端口号”“目的端口号”,协议号IP协议的协议号为4TCP的协议号为6这样的一个五元组来标识一个通信通信的双方在发送消息时消息的头部会带着这样的五元组。