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 秒,那么就会重用这个连接,然后就可以正常使用该端口了。

相关推荐
4SAPI12 小时前
企业大模型API服务商推荐:从多模型接入到AI API Gateway的技术选型分析
人工智能·php
ITxiaobing202317 小时前
企业级 IP 定位服务选型:从精度、字段到部署架构的工程化考量
tcp/ip
子非鱼a17 小时前
【WEB】[NewStarCTF 2023 公开赛道]include 0。0
php
DevUp18 小时前
停更老站往哪搬:PHP 老站的五条出路(番外七)
php·cms
专业程序开发源21 小时前
springboot旅游推荐系统82074-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·php·课程设计·旅游
爱研究的小梁1 天前
异构链路科普:5G/4G、卫星、专网、WiFi、光纤,如何聚合工作?
网络·网络协议·udp·信息与通信
wuyk5551 天前
《WiFi 嵌入式物联网开发全套实战》| 第 12 章 Linux 系统 WiFi 常用命令全集:iw/iwlist/ip/wpa_cli 实战
linux·网络·stm32·物联网·tcp/ip
sbjdhjd1 天前
从“删除后重生”到认证绕过:PHP 常驻内存实验与 Cacti remote_agent 命令执行链路复盘
安全·web安全·网络安全·数据挖掘·php·网络攻击模型·安全架构
JaguarJack1 天前
PHP 8.6 只是个小版本,三十项弃用却已在为 PHP 9.0 铺路
后端·php·服务端
BingoGo1 天前
PHP 8.6 只是个小版本,三十项弃用却已在为 PHP 9.0 铺路
后端·php