Python技术迷

TCP 和 UDP 的区别有哪些?

朋友在群里问我:“东哥,TCP和UDP到底有啥区别啊?我老糊涂了,能不能说人话一点?”其实这种问题吧,说简单也简单,说细节又能聊一天。正好,我还没拆外卖,边吃边唠吧。

场景一:送外卖和发快递的区别

就拿我刚才点外卖举个例子啊,TCP就像顺丰快递,送之前得确认你在不在家,然后每一步都要打电话确认一下,“哥们,你的快递到了,门口有人吗?”没送到还得给你退回去。而UDP就像你下楼拿那种共享单车的广告单子,直接一把塞你门口,没人理也不管,扔了算。

你在写Python socket程序的时候就能感觉出来,TCP这种写法你得先建立连接:

import socket

# TCP
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('127.0.0.1', 8080))
sock.send(b'hello tcp')
data = sock.recv(1024)
sock.close()

UDP可就简单粗暴了,直接“发了溜”,谁收谁不收,没人管:

import socket

# UDP
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(b'hello udp', ('127.0.0.1', 8080))
sock.close()

是不是,看着就随意。

场景二:丢包和重发,兄弟你到底稳不稳

我跟你讲,有一次在公司楼下抽烟,和运维聊天,他吐槽UDP,说有个系统老丢包,现场一片骂声。为啥?UDP发包就跟撒传单一样,掉地上就掉地上了,没人帮你捡。而TCP是那种“每发一个包都要签收”的,没收到还要重发,甚至有个校验和,确认内容没出错。

举个极端点的场景,视频直播、语音通话这些延迟要求高但丢点数据无所谓的,一般都用UDP。像文件传输、网页访问,得保证数据不能错的,肯定得TCP。

场景三:连接管理,谁更社恐

TCP发消息之前得先三次握手,真像我这种社恐,见面得先确认对方是个人再聊天,最后还要四次挥手才能走(四次挥手,听着怪别扭吧,就是协议设计的原因),反正离不开“你在吗?我在。你真在?我真在。” UDP完全是“哥们,有事说事,没事我走了。” 你连“你在吗”都懒得问。

场景四:包大小和粘包问题

有次小李问我,为什么UDP经常发不出大文件?其实UDP最大能发的数据有个限制(一般来说是64K,但实际常见要远小于这个,跟操作系统和网络设备有关),超过了就得拆分。TCP就不一样了,它自己帮你拆好包,粘好包,顺序还帮你排好。

不过顺序这块也有坑,比如你连续发几个小包,TCP可能合成一个大包再发出去,这就是所谓的“粘包”,写代码时候要注意处理拆包。不然你客户端recv出来的数据就一坨糊。


场景五:可靠性和速度,鱼和熊掌

我上次给公司做个小项目,要实时监控现场设备,现场传感器用UDP数据就特别快,延迟低。老板非得让我改成TCP,搞得我头大。TCP你要等对方收到了才发下一个包,慢是慢,但安全;UDP就是“谁怕谁啊,快就完了”,丢了就丢了。

随手写个UDP服务端和客户端吧,自己在家跑跑试试,没那么神秘:

UDP服务端

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('0.0.0.0', 9999))
whileTrue:
    data, addr = sock.recvfrom(1024)
    print(f"收到来自{addr}的信息:{data.decode()}")
# 不需要ack,收到就算完事

UDP客户端

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(b'UDP打招呼', ('127.0.0.1', 9999))
sock.close()

TCP你自己试着写下,记得client和server都得先连接再通信。

最后懒得再搬砖总结了哈,朋友们记住一句话:TCP重安全,UDP重效率,生活中用啥全看需求,别死磕。写代码之前,先问问自己,“我更在乎速度还是更在乎安全?”答案自然就出来了。

-END-

我为大家打造了一份RPA教程,完全免费:https://www.songshuhezi.com/rpa.html

🔥虎哥私藏精品🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领