首先回答这个问题,答案是肯定的,TCP连接和UDP连接可以同时监听一个端口。
一、端口是干什么的
在软件开发过程中,你一定遇到过Address already in use这个错误,系统向你返回该端口已经被占用的错误,这时候你会更改一个端口,或者停止已经存在的端口服务(我们平时使用的http基本都是TCP连接)。
为什么问题是TCP和UDP能不能共用端口,而不是HTTP, FTP? 首先我们先来了解一下端口是干嘛的。
端口是计算机网络中的术语,用于标识特定的进程,通常和IP地址一起出现,形成一个完整的网络地址。通过IP地址我们可以找到进程所在的服务器,通过端口我们可以找到进程所在服务器上的内存地址,从而使得数据包能够正确的发送给特定的进程。在TCP/IP 五层协议中,IP地址信息存在于网络层,port信息存在于传输层。
我们常常使用的传输层协议有TCP和UDP,它们的数据包格式也不一样,下面是两个传输层协议报文样式。
TCP
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|P|R|S|F| |
| Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
UDP
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| Source | Destination |
| Port | Port |
+--------+--------+--------+--------+
| | |
| Length | Checksum |
+--------+--------+--------+--------+
|
| data octets ...
+---------------- ...
Source Port 指的是源端口号,Destination Port 是目的端口,不同的传输层协议对端口的定义是一致的,是一个16位无符号型整数,取值范围为0~65535,所以单个ip最多有65536个端口。
看完上面的端口概念,你可能理解了什么是端口,但是对于题目还是有疑问, 同一个端口我有两个连接,数据不会错乱么??? 这个不用担心,操作系统都帮你做好分类了,当数据包进来后只会找这个数据包对应的连接,绝对不会与别的连接扯上关系,问题来了,这是如何实现的?
二、数据包是如何正确进入应用程序的
你一定听说过四元组这个概念,讲的是通过一个四元组(源地址,源端口,目的地址,目的端口)可以确定一条网络连接,当然这个结论成立的话有个前提,是同一个传输协议。更准确一点来说,通过一个五元组(源地址,源端口,目的地址,目的端口,传输协议)可以确定一条连接。这个传输协议可以是TCP,也可以是UDP。
当数据包通过网线进入设备网络,最终被应用程序读取,经过多个层次的处理。
进入数据链路层后,解析以太网首部,保留网络协议数据,进入网络层。
进入网络层后,解析IP首部,将数据包送给不同的网络协议栈。
进入传输层后,解析传输协议类型,不同的传输协议会有不同的socket连接。
进入应用层,通过层层筛选,数据被正确的送入指定的应用进程。
三、实际测试
说了这么多,我们找一台linux服务器实际测试一下。
一共编写了4个C文件,分别实现tcp_server.c ,tcp_client.c,udp_server.c , udp_client.c。
1、第一组测试
启动tcp_server , udp_server 共同监听9001端口 。 程序可以同时运行。
2、第2组测试
同时启动tcp_server,udp_server,启动tcp_client , tcp_server收到消息,udp_server未收到到消息。
3、第3组测试
同时启动tcp_server,udp_server,启动udp_client , tcp_server未收到消息,udp_server收到消息。
四、总结
这是最近经常会碰到的一道面试题,这个问题考察了传输层协议相关的知识,由于我们平时使用时很少碰到udp,tcp连接同时使用一个端口的情况,所以会有所疑惑,但是当完全理清五层协议中每一层的功能时,就能很好的解答这个问题。
我是烤鱼,后面会给大家带来更多面试题的解答,求点赞、收藏、关注。