TCP 和 UDP 的端口

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

可以的,网络层会根据你IP包头的协议号就知道该数据包是TCP还是UDP,就确定发给哪一个模块处理

原因在于:操作系统内核管理 socket 的时候,区分的不是单纯的端口号,而是 (协议, 本地IP, 本地端口, 远

端IP, 远端端口) 这个五元组。

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

如果多个TCP服务进程绑定的端口 IP地址和端口号相同,那就不行,执行bind()会报错

但如果那个Socket设置了SO_REUSEADDR,只要两个进程bind的IP不相同。那就是可以的

如何解决服务端进程重启时,报错“Address already in use”的问题?

当我们重启TCP服务进程的时候,意味着服务端发起了关闭连接操作。于是就是会经过四次挥手。而对于

主动关闭方,会在TIME_WAIT状态停留一段时间,这个时间大概是2MSL

当tcp服务进程重启时,服务端会出现TIME_WAIT状态的连接,TIME_WAIT状态的连接仍然没有释放ip+port

故执行bind()会报错,address already in use

要解决这个问题,我们可以对Socket 设置 so_reuseadd

这样即使存在一个和bind ip和port一样的TIME_WAIT状态的连接,那还是可以绑定成功,从而重启成功

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

确定唯一的连接是靠五元组(协议,源IP,源端口,目标IP,目标端口),只要其中一个不一样就表明是不同

的连接

内核是通过四元组信息来定位一个 TCP 连接的

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

针对这个问题,那得看客户端连的是不是都是同一个服务器(ip,port相同)

如果不一样的话,端口是可以复用的。

一样的话,就会被端口的数量限制住

所以,如果客户端都是与不同的服务器建立连接,即使客户端端口资源只有几万个, 客户端发起百万级连接也是没问题的(当然这个过程还会受限于其他资源,比如文件描述符、内存、CPU 等)。

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

打开tcp_tw_reuse。你客户端调用connect()时,如果发现已经有链接占用ip和port,会检查原有连接是否是

TIME_WAIT状态,然后检查该链接是否存在超过了1s,如果是的话,那就复用它

不过这种方式比较激进,Linux2.4已经被废弃了