TCP和UDP可以使用同一个端口号吗?
TCP和UDP可以使用同一个端口号吗?
首先说答案:可以。怎么理解呢?
我想这个问题要从计算机网络通信谈起,学过计算机网络的同学,可能都还记得7层或者4层网络模型,TCP/UDP属于其中的传输层协议,在传输层之下是网络层,网络层主要通过IP协议来进行通信,这也是我们日常程序开发中能够接触到的最底层了,再往下的数据链路层和物理层就不是我们这些普通程序员需要关心的了。

IP
我们先具体看下网络层。在IP网路层,发送者向接收者传输数据的时候,首先需要知道接收者的IP地址,IP地址可以在网络中唯一标识一台计算机端口号
这就像快递员到达了一栋大楼,下一步它怎么把快递送到对应的用户手中呢?聪明的你一定想到了,那就是门牌号。
在计算机中,端口号就是门牌号。计算机的操作系统可以为不同的程序绑定不同的端口号,这样发送者发送数据时不仅要设置接收者的IP,还要加上接收者的端口号,如此接收者所在的计算机就能把数据转发给正确的程序了。
TCP/UDP
那么TCP和UDP能不能使用同一个端口号呢?其实在查找端口号之前还有一个传输层协议的处理过程,操作系统收到数据后,会先查看数据包使用的是TCP协议还是UDP协议,然后再根据协议进行不同的解析处理,提取到数据后,再转发到拥有对应端口的程序。
所以TCP和UDP是可以使用相同的端口号的,这在现实中也是常见的。比如 DNS(域名系统)可能需要同时支持 TCP 和 UDP 查询,这两种查询就都可以通过53这个标准端口来进行接收和响应。
但是在同一个传输协议下,端口号就不能相同了。如果相同,操作系统的协议栈就不知道该把这个数据包转给哪个程序了,这种设计会增加很多麻烦。
有的同学可能会观察到一个现象,那就是同一个计算机上的多个网站可以共享80或者443端口,这其实是应用层的能力,这些网站都寄宿在同一个Web服务器程序上,这个Web服务器程序绑定了80端口,Web服务器收到数据后再根据HTTP协议中的主机头(可以理解成域名)转发给不同的网站程序。
还有,如果你的电脑上有多个IP,那就更没有问题了。不同的IP代表不同的网络接口,即使都使用TCP协议,只要IP不同,端口号一样也完全不会冲突。
“IP+传输层协议+端口号”就是我们常说的套接字,它能确保数据从一个网络程序传递到另一个网络程序。大家如果直接使用TCP和UDP编程,就需要手动为套接字设置这几个参数。
示例
口说无凭,再给大家写个demo,使用go语言,简单易懂:
下边的程序会启动一个TCP服务器和一个UDP服务器,它们绑定相同的IP和端口号。这里为了方便测试,使用了127.0.0.1这个本机IP,你也可以换成局域网或者公网IP。
package main
import (
"fmt"
"net"
"os"
)
func main() {
// 定义监听的端口
port := "127.0.0.1:12345"
// 启动TCP服务器
go startTCPServer(port)
// 启动UDP服务器
startUDPServer(port)
}
func startTCPServer(port string) {
// 通过TCP协议监听端口
l, err := net.Listen("tcp", port)
if err != nil {
fmt.Println("Error listening:", err.Error())
os.Exit(1)
}
defer l.Close()
fmt.Println("TCP Server Listening on " + port)
// 持续接收TCP数据
for {
conn, err := l.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
os.Exit(1)
}
fmt.Println("Received TCP connection")
conn.Close()
}
}
func startUDPServer(port string) {
// 通过UDP协议监听端口
addr, err := net.ResolveUDPAddr("udp", port)
if err != nil {
fmt.Println("Error resolving: ", err.Error())
os.Exit(1)
}
conn, err := net.ListenUDP("udp", addr)
if err != nil {
fmt.Println("Error listening: ", err.Error())
os.Exit(1)
}
defer conn.Close()
fmt.Println("UDP Server Listening on " + port)
buffer := make([]byte, 1024)
// 持续接收UDP数据
for {
n, _, err := conn.ReadFromUDP(buffer)
if err != nil {
fmt.Println("Error reading: ", err.Error())
continue
}
fmt.Printf("Received UDP packet: %s\n", string(buffer[:n]))
}
}
然后再创建两个客户端,一个是TCP客户端:
package main
import (
"fmt"
"net"
"os"
)
func main() {
// 连接到服务器
conn, err := net.Dial("tcp", "localhost:12345")
if err != nil {
fmt.Println("Error connecting:", err.Error())
os.Exit(1)
}
defer conn.Close()
// 发送数据
_, err = conn.Write([]byte("Hello TCP Server!"))
if err != nil {
fmt.Println("Error sending data:", err.Error())
return
}
fmt.Println("Message sent to TCP server")
}
另一个是UDP客户端:
package main
import (
"fmt"
"net"
"os"
)
func main() {
ServerAddr, err := net.ResolveUDPAddr("udp", "localhost:12345")
if err != nil {
fmt.Println("Error resolving: ", err.Error())
os.Exit(1)
}
conn, err := net.DialUDP("udp", nil, ServerAddr)
if err != nil {
fmt.Println("Error dialing: ", err.Error())
os.Exit(1)
}
defer conn.Close()
// 发送数据
_, err = conn.Write([]byte("Hello UDP Server!"))
if err != nil {
fmt.Println("Error sending data:", err.Error())
return
}
fmt.Println("Message sent to UDP server")
}
我们可以看到,客户端发起请求的时候都使用了 localhost:12345 这个目标地址,其中的localhost 实际上是个域名,它会被本地计算机解析为 127.0.0.1。这块不清楚的可以看我之前写的这篇:
实际运行效果如下:

最后总结下:在网络通信中,同一台计算机中,TCP和UDP协议可以使用相同的端口号。每个网络进程中的套接字地址都是唯一的,由三元组(IP地址,传输层协议,端口号)标识。操作系统会根据数据包中的传输层协议(TCP或UDP)以及端口号,将接收到的数据正确地交付给相应的应用程序。
TCP和UDP可以使用同一个端口号吗?的更多相关文章
- python网络编程,通过服务名称和会话类型(tcp,udp)获取端口号,简单的异常处理
作为一个php程序员,同时有对网络方面感兴趣,php就比较蛋疼了,所以就抽了些时间看python 之前学python基础因为工作原因,断断续续的看了个基础,差不多是可以写代码了 最近在看<pyt ...
- 图解 TCP/IP 第六章 TCP与UDP 笔记6.1 传输层的作用
图解 TCP/IP 第六章 TCP与UDP 笔记6.1 传输层的作用 传输层必须指出这个具体的程序,为了实现这一功能,使用端口号这样一种识别码.根据端口号,就可以识别在传输层上一层的应用程 ...
- TCP与UDP 笔记
本文整理自:<图解TCP/IP 第5版>作者:[日] 竹下隆史,[日] 村山公保,[日] 荒井透,[日] 苅田幸雄 著译者:乌尼日其其格出版时间:2013-07 TCP提供可靠的通信传输, ...
- mac地址、IP地址和端口号
看了很多遍,才整理出来我对整个通信过程的理解,大致如下,后期会不断学习补充更正: 在利用TCP/IP协议族进行通信的时候,有三个比较关键的确认身份的信息:mac地址.IP地址和端口号. mac地址是在 ...
- Service Name Port Number Transport Protocol tcp udp 端口号16bit
https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol The DHCP employs a connectionless ...
- TCP、UDP、IP 协议分析
http://rabbit.xttc.edu.cn/rabbit/htm/artical/201091145609.shtml http://bhsc881114.github.io/2015/06 ...
- TCP、UDP、IP协议分析
此篇文章的原创作者是:草根老师博客(程姚根) chengyaogen.blog.chinaunix.net 感谢原作者! 互连网早期的时候,主机间的互连使用的是NCP协议.这种协议本身有很多缺陷,如: ...
- (转)TCP、UDP、IP协议
原文地址:http://blog.chinaunix.net/uid-26833883-id-3627644.html 互连网早期的时候,主机间的互连使用的是NCP协议.这种协议本身有很多缺陷,如 ...
- TCP/IP协议栈与数据包封装+TCP与UDP区别
ISO制定的OSI参考模型的过于庞大.复杂招致了许多批评.与此对照,由技术人员自己开发的TCP/IP协议栈获得了更为广泛的应用.如图2-1所示,是TCP/IP参考模型和OSI参考模型的对比示意图. T ...
- CentOS7查看开放端口命令及开放端口号
CentOS 7查看以开放端口命令:firewall-cmd —list-ports 查看端口是否开放命令:第一个方法就是使用lsof -i:端口号命令行,例如lsof -i:80.如果没有任何信息输 ...
随机推荐
- 兄弟组件互相传递值-this.$bus.$emit与this.$bus.$on
B组件向C组件传递一个值. 一种组件间通信的方式, 适用于任意的组件间通信. 适用于任意的组件间通信. 适用于任意的组件间通信. 通过this.$bus.$emit('事件名',数据)进行提供数据 通 ...
- 【JS逆向百例】某音乐网分离式 webpack 非 IIFE 改写实战
关注微信公众号:K哥爬虫,QQ交流群:808574309,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途 ...
- Govulncheck v1.0.0 发布了!
原文在这里 原文作者:Julie Qiu, for the Go security team 发布于 13 July 2023 我们很高兴地宣布,govulncheck v1.0.0 已经发布,同时还 ...
- Git如何拉取指定远程分支
转载来自https://www.jianshu.com/p/856ce249ed78 目的 我们想要获取到代码仓库中分支"a" 中的文件到本地,我了解到有三种方法. 代码仓库 ...
- vs版本与version(内部版本号)的关系表table
为什么要查vs版本与内部verion的对应关系? 因为c++的项目需要对应的vs版本,给大型的c++项目升级vs版本是个耗时的工程,所以一般情况下开发者都会安装多个版本的vs. 对于sln文件,以文本 ...
- Python Coroutine 池化实现
Python Coroutine 池化实现 池化介绍 在当今计算机科学和软件工程的领域中,池化技术如线程池.连接池和对象池等已经成为优化资源利用率和提高软件性能的重要工具.然而,在 Python 的协 ...
- SqlSugar分组查询
一.分组查询和使用 1.1 语法 只有在聚合对象需要筛选的时候才会用到Having,一般分组查询用不到可以去掉 var list = db.Queryable<Student>() ...
- python自动化高效办公第二期,带你项目实战【二】{数据可视化、发送邮件(定时任务监控)、python聊天机器人(基于微信、钉钉)}
相关文章和数据源: python自动化高效办公第二期,带你项目实战[一]{excel数据处理.批量化生成word模板.pdf和ppt等自动化操作} Python自动化办公--Pandas玩转Excel ...
- Python 原生Socket实现端口扫描
端口扫描,就是逐个对一段端口或指定的端口进行扫描.通过扫描结果可以知道一台计算机上都提供了哪些服务,Python中使用Socket即可实现对特定端口的探测,以及对C段的扫描. 扫描目标主机Banner ...
- Windows XP Professional with Service Pack 3 (x86)
Windows XP Professional with Service Pack 3 (x86) 链接:https://pan.baidu.com/s/1p99vLx5psoq9K4ONlRpkZA ...