陷阱题,淋漓尽致体现了中文的博大精深!
由于和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:8888在1.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。