4.18 TCP 和 UDP 可以使用同一个端口吗?

目录

[TCP 和 UDP 可以同时绑定相同的端口吗?](#TCP 和 UDP 可以同时绑定相同的端口吗?)

[多个 TCP 服务进程可以绑定同一个端口吗?](#多个 TCP 服务进程可以绑定同一个端口吗?)

[重启 TCP 服务进程时,为什么会有"Address in use"的报错信息?](#重启 TCP 服务进程时,为什么会有“Address in use”的报错信息?)

[重启 TCP 服务进程时,如何避免"Address in use"的报错信息?](#重启 TCP 服务进程时,如何避免“Address in use”的报错信息?)

客户端的端口可以重复使用吗?

[多个客户端可以 bind 同一个端口吗?](#多个客户端可以 bind 同一个端口吗?)

[客户端 TCP 连接 TIME_WAIT 状态过多,会导致端口资源耗尽而无法建立新的连接吗?](#客户端 TCP 连接 TIME_WAIT 状态过多,会导致端口资源耗尽而无法建立新的连接吗?)

[如何解决客户端 TCP 连接 TIME_WAIT 过多,导致无法与同一个服务器建立连接的问题?](#如何解决客户端 TCP 连接 TIME_WAIT 过多,导致无法与同一个服务器建立连接的问题?)


因为「监听」这个动作是在 TCP 服务端网络编程中才具有的,而 UDP 服务端网络编程中是没有「监听」这个动作的。

TCP 和 UDP 服务端网络相似的一个地方,就是会调用 bind 绑定端口。

TCP 和 UDP 可以同时绑定相同的端口吗?

在数据链路层中,通过 MAC 地址来寻找局域网中的主机。在网际层中,通过 IP 地址来寻找网络中互连的主机或路由器。在传输层中,需要通过端口进行寻址,来识别同一计算机中同时通信的不同应用程序。

传输层的「端口号」的作用,是为了区分同一个主机上不同应用程序的数据包。

传输层有两个传输协议分别是 TCP 和 UDP,在内核中是两个完全独立的软件模块。

多个 TCP 服务进程可以绑定同一个端口吗?

如果两个 TCP 服务进程同时绑定的 IP 地址和端口都相同,那么执行 bind() 时候就会出错,错误是"Address already in use"

如果想多个进程绑定相同的 IP 地址和端口,也是有办法的,就是对 socket 设置 SO_REUSEPORT

重启 TCP 服务进程时,为什么会有"Address in use"的报错信息?

当 TCP 服务进程重启时,服务端会出现 TIME_WAIT 状态的连接,TIME_WAIT 状态的连接使用的 IP+PORT 仍然被认为是一个有效的 IP+PORT 组合,相同机器上不能够在该 IP+PORT 组合上进行绑定,那么执行 bind() 函数的时候,就会返回了 Address already in use 的错误

而等 TIME_WAIT 状态的连接结束后,重启 TCP 服务进程就能成功。

重启 TCP 服务进程时,如何避免"Address in use"的报错信息?

对 socket 设置 SO_REUSEADDR 属性

客户端的端口可以重复使用吗?

客户端在执行 connect 函数的时候,会在内核里随机选择一个端口,然后向服务端发起 SYN 报文,然后与服务端进行三次握手。

客户端的端口选择的发生在 connect 函数,内核在选择端口的时候,会从 net.ipv4.ip_local_port_range 这个内核参数指定的范围来选取一个端口作为客户端端口。

可用端口号 61000 - 32768 = 28232 个

TCP 连接是由四元组(源IP地址,源端口,目的IP地址,目的端口)唯一确认的,那么只要四元组中其中一个元素发生了变化,那么就表示不同的 TCP 连接的。所以如果客户端已使用端口 64992 与服务端 A 建立了连接,那么客户端要与服务端 B 建立连接,还是可以使用端口 64992 的,因为内核是通过四元祖信息来定位一个 TCP 连接的,并不会因为客户端的端口号相同,而导致连接冲突的问题。

多个客户端可以 bind 同一个端口吗?

一般而言,客户端不建议使用 bind 函数,bind 函数虽然常用于服务端网络编程中,但是它也是用于客户端的。

客户端是在调用 connect 函数的时候,由内核随机选取一个端口作为连接的端口。

要看多个客户端绑定的 IP + PORT 是否都相同,如果都是相同的,那么在执行 bind() 时候就会出错,错误是"Address already in use"。

客户端 TCP 连接 TIME_WAIT 状态过多,会导致端口资源耗尽而无法建立新的连接吗?

客户端是否都是与同一个服务器(目标地址和目标端口一样)建立连接,如果同一个服务器(目标地址和目标端口一样)建立连接,那么如果客户端 TIME_WAIT 状态的连接过多,当端口资源被耗尽,就无法与这个服务器再建立连接了。因为只要客户端连接的服务器不同,端口资源可以重复使用的

如何解决客户端 TCP 连接 TIME_WAIT 过多,导致无法与同一个服务器建立连接的问题?

打开 net.ipv4.tcp_tw_reuse 这个内核参数,

因为开启了这个内核参数后,客户端调用 connect 函数时,如果选择到的端口,已经被相同四元组的连接占用的时候,就会判断该连接是否处于 TIME_WAIT 状态,如果该连接处于 TIME_WAIT 状态并且 TIME_WAIT 状态持续的时间超过了 1 秒,那么就会重用这个连接,然后就可以正常使用该端口了。

相关推荐
JaguarJack1 天前
FrankenPHP 原生支持 Windows 了
后端·php·服务端
BingoGo1 天前
FrankenPHP 原生支持 Windows 了
后端·php
JaguarJack2 天前
PHP 的异步编程 该怎么选择
后端·php·服务端
BingoGo2 天前
PHP 的异步编程 该怎么选择
后端·php
JaguarJack3 天前
为什么 PHP 闭包要加 static?
后端·php·服务端
ServBay4 天前
垃圾堆里编码?真的不要怪 PHP 不行
后端·php
用户962377954484 天前
CTF 伪协议
php
blasit5 天前
笔记:Qt C++建立子线程做一个socket TCP常连接通信
c++·qt·tcp/ip
BingoGo6 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack6 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端