ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-07-26 22:32:27  阅读:155  来源: 互联网

标签:UDP 绑定 端口 TCP IP地址 连接 客户端


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

            

 

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

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

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

  当主机收到数据包后,可以在IP包头的协议号字段知道该数据包是TCP/UDP,所以可以根据这个信息确定送给那个模块(TCP/UDP)处理,送到传输层中的TCP/UDP模块中的报文根据端口号确定送给哪个应用程序处理。

  因此,TCP/UDP各自的端口号也相互独立。

二、多个TCP服务器进程可以绑定同一个端口号吗

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

  注意,必须IP地址和端口号都相同。

  如果进程绑定了0.0.0.0地址,这代表了任意地址,则此时只要有另一进程绑定了一致的端口号,则都会报错。

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

  在实践中,我们可能会经常碰到一个问题,当 TCP 服务进程重启之后,总是碰到“Address in use”的报错信息,TCP 服务进程不能很快地重启,而是要过一会才能重启成功。

  这是为什么呢?

  这是因为当我们重启TCP服务进程时,意味着通过服务器端发起了关闭连接操作,于是就会经过四次挥手,而对于主动关闭方,会在TIME_WAIT这个状态里停留一段时间,这个时间大约为2MSL。

 

   在TIME_WAIT状态下的IP+PORT组合仍然被认为是一个有效的组合,此时相同机器就不能够在该IP+PORT组合上进行绑定。

  对于此种情况,我们可以在调用bind前,对socket设置SO_REUSEADDR属性。

int on = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

  SO_REUSEADDR 作用是:如果当前启动进程绑定的 IP+PORT 与处于TIME_WAIT 状态的连接占用的 IP+PORT 存在冲突,但是新启动的进程使用了 SO_REUSEADDR 选项,那么该进程就可以绑定成功。

  对于前面提到的问题:如果TCP服务进程A绑定了0.0.0.0:8080,而此时TCP服务进程去绑定192.168.1.100:8080会出错。

  这个问题也可以使用SO_REUSEADDR拒绝,因为它的另外一个作用是:绑定的IP地址+端口时,只要IP地址不是正好(exactly)相同,那么允许绑定。

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

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

 

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

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

  但是,如果多个客户端bind同一个IP地址+PORT组合,还是会出错的。一般而言,客户端也不建议使用bind函数,因为客户端的端口通常没什么意义。

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

  针对这个问题要看,客户端是否都是与同一个服务器(IP地址+PORT一样)建立连接。

  如果客户端都是与同一服务器(IP地址+PORT一样)建立连接,那么TIME_WAIT状态过多,当端口资源被耗尽,就无法与这个服务器再建立连接了。

  但是,只要客户端连接的服务器不同,端口资源是可以重复使用的(四元组)。

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

  针对这个问题,解决方法是打开net.ipv4.tcp_tw_reuse这个内核参数。

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

 

标签:UDP,绑定,端口,TCP,IP地址,连接,客户端
来源: https://www.cnblogs.com/unrealCat/p/16522932.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有