字节一面:TCP 和 UDP 可以使用同一个端口吗?

2024-11-05 22:00

陷阱题,淋漓尽致体现了中文的博大精深!

image-20241105220025362

由于和Port Number直接打交道的至少5个角色,分别为:

  • TCP/UDP

  • 客户端使用TCP的应用进程

  • 客户端使用UDP的应用进程

  • 服务端使用TCP的服务进程

  • 服务端使用UDP的服务进程

故,按序细分为5个小问题。

Q1: May TCP and UDP use the same Port Number?

Yes。

TCP 端口号范围(0-65535),一共65536个端口,除了0被操作系统保留,其他的65535个端口,TCP可以自由使用。

UDP 端口号范围(0-65535),一共65536个端口,除了0被操作系统保留,其他的65535个端口,UDP可以自由使用。

UDP端口号53被DNS占用(Not Available),难道TCP 53号端口就不能使用了?

当然可以使用!

UDP Port Number 53 is NOT Available

TCP Port Number 53 is Available

尽管TCP 53端口可以使用,但是IANA官方依然提前将她许配给了DNS(Domain Name System)。许配链接:

https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt

现实是这样的,当DNS服务器进程启动时,会侦听以下端口:

  • TCP Listening Port 53

  • UDP Listening Port 53

    意味着DNS服务器进程,会同时使用TCP/UDP 53号端口。

  • UDP 用于处理≤ 576字节(包含IP/UDP)查询请求

  • 如果查询报文超出以上限制,客户端会使用TCP发出查询请求。DNS服务器正在TCP 53号端口恭候阁下光临

不光53号端口,所有的1-1023知名端口(Well-Known), 会同时分配给一个服务(Service)。

这里的同时的意思是,Both TCP and UDP

IANA老专家给各种服务(DNS/HTTP)等等灵活性,可以使用TCP来实现自己的服务,也可以使用UDP实现自己的服务,或者同时。

80端口分配给了HTTP,但是HTTP只使用TCP满足自己的需求。

直接后果就是UDP 80端口一直闲置不用(Available)!

这个UDP 80端口别的进程能使用吗?

当然可以,只要有Super User的权限。

53号端口,同时(TCP/UDP)被一个DNS服务进程占用。

80号端口,TCP 80被HTTP服务进程占用,UDP 80被别的服务进程占用。

Q2: 多个客户端进程(不同的Process ID)能同时使用一个TCP端口号?

No。

客户端IP = 1.1.1.1,TCP端口号 = 8888,这个TCP/IP组合 1.1.1.1:8888只能被一个使用TCP的进程独占。只要这个进程没有释放端口资源(TIME_WAIT),其他进程就无法使用。即使这个8888端口资源最终释放了(CLOSED),但也只能被一个(ONLY)进程独占使用!客户端还有一个loopback = 127.0.0.1,这个IP/TCP组合**127.0.0.1:88881.1.1.1:8888被占用的情况下,其他进程可以使用吗?当然可以。127.0.0.1:8888** 与 1.1.1.1:8888 彼此独立自主(正交)。

无论是TCP动态分配的端口,还是客户端使用bind()自主指定的端口,本回答都使用。Q3: 多个客户端进程(不同的Process ID)能同时使用一个UDP端口号?No.但是,这个NO和上文的NO差别还是有的。客户端IP = 1.1.1.1,如果客户端没有使用bind() UDP 8888端口,而是由操作系统临时分配8888端口号,客户端使用该端口发包自然是独占的,其他进程无法使用。问题来了,客户端不发包的时候,其他进程能否使用8888端口号?可以。这不就是UDP无连接(Connectionless)的最好体现吗?

但是,UDP 8888被别的进程使用了,服务器返回的报文不就被其它进程取走了吗?

是的,这是一个潜在的数据安全问题,这种UDP应用场景美其名曰**Unconnected UDP。使用Unconnected UDP的场景,通常是客户端到服务器的单向(Unidirection)通信**。

如果

客户端IP = 1.1.1.1,使用bind() 绑定UDP 8888端口,只要该进程不Closed,这个UDP 8888端口就是独占的,其它进程是无法使用的。

UDP通信的两端,都强制使用bind()绑定了IP、UDP端口号,通信四元组:

  • 客户端IP = 1.1.1.1

  • 客户端UDP =8888

  • 服务器IP = 2.2.2.2

  • 服务器端口= 9999

是不是有TCP连接的样子了?

是的,将这种UDP应用场景命名为**Connected UDP。这种Connected UDP,就是最常用的双向(Bidirectional)通信场景。Q4: 多个服务器进程(不同的Process ID)能同时侦听(Listening)一个TCP端口号?默认(Default)情况下不可以,但是如果配置SO_REUSEADDR**,是可以的。

服务器2块网卡,一个loopback,IP地址分别为

  • IP =2.2.2.2

  • IP=3.3.3.3

  • IP =127.0.0.1

  • 服务进程A Listening: *:80

  • 服务进程B Listening: 2.2.2.2:80

进程A接受任何目的IP = self的TCP Port =80连接请求,self包含 127.0.0.1、2.2.2.2、3.3.3.3。

进程B只接受任何目的IP = 2.2.2.2的TCP Port =80连接请求。

客户端1连接服务器2.2.2.2:80,由服务器进程B处理。

客户端2连接服务器3.3.3.3:80,由服务器进程A处理。

如果网卡(2.2.2.2)掉线,

客户端1连接服务器2.2.2.2:80,由服务器进程A处理。

客户端2连接服务器3.3.3.3:80,由服务器进程A处理。

如果2块网卡都掉线,

客户端1连接超时。

客户端2连接超时。

为何叫SO_REUSEADDR?

Socket Option Reuse Address,由于“ =0.0.0.0”,其包含2.2.2.2,这是Reuse Address的由来。Q5: 多个服务器进程(不同的Process ID)能同时侦听(Listening)一个UDP端口号?参考Q4答案。还有一个SO_REUSEPORT忽略了,用在什么地方呢?组播(Multicast)、广播(Broadcast)。一个组播IP= 239.1.1.1, UDP Port= 8888,组播接收主机有2个进程都需要接收。只要SO_REUSEPORT就可以梦想成真。一个组播Packet被2个进程各copy一次。为何叫SO_REUSEPORT?*

Socket Option Reuse Port,这里不仅包含Port的重用(比如8888),还包含Address的重用(239.1.1.1)。

为了区别于SO_REUSEADDR,故命名为SO_REUSEPORT。

相关文章
热点文章
精彩视频
Tags

站点地图 在线访客: 今日访问量: 昨日访问量: 总访问量: