利用Python两分钟了解TCP和UDP编程实现
TCP和UDP是OSI七层模型中传输层的两个协议,对应了两种传输方式
特点如下,更多更详细请访问:TCP与UDP的全面对比
|
UDP |
TCP |
是否连接 |
无连接 |
面向连接 |
是否可靠 |
不可靠传输,不使用流量控制和拥塞控制 |
可靠传输,使用流量控制和拥塞控制 |
连接对象个数 |
支持一对一,一对多,多对一和多对多交互通信 |
只能是一对一通信 |
传输方式 |
面向报文 |
面向字节流 |
首部开销 |
首部开销小,仅8字节 |
首部最小20字节,最大60字节 |
适用场景 |
适用于实时应用(IP电话、视频会议、直播等) |
适用于要求可靠传输的应用,例如文件传输 |
而在Python下,两者的编程实现主要有以下区别:
|
UDP |
TCP |
socket创建 |
socket.socket(socket.AF_INET, socket.SOCK_DGRAM) |
socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
数据传输 |
sendto()、recvfrom() 不是一对一 所以要指明对方地址 |
send()、recv() |
与对方构建连接 |
无需连接,直接向对方IP地址传输 |
需要使用listen()、accept()、connect(),需要双方互相“握手” |
下面让我们看看在Python下两者的具体实现,从而理解其主要区别:
##UDP服务端 import socket #建立IPv4,UDP的socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #绑定端口: s.bind(('127.0.0.1', 9999)) #不需要开启listen,直接接收所有的数据 print('Bind UDP on 9999') while True: #接收来自客户端的数据,使用recvfrom data, addr = s.recvfrom(1024) print('Received from %s:%s.' % addr) s.sendto(b'hello, %s!' % data, addr)
##UDP客户端 import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #不需要建立连接: for data in [b'Michael', b'ALice', b'FF']: #发送数据到客户端: s.sendto(data, ('127.0.0.1', 9999)) #接收来自客户端的数据: print(s.recvfrom(1024)[0].decode('utf-8')) s.close()
——————————————————快乐分界线—————————————————————
##TCP服务端 #导入socket库 import socket import threading import time def deal_by_tcp(sock, addr):#新线程执行的函数 print('Accept connection from %s:%s...'.format(addr[0],addr[1])) sock.send(('Welcome!').encode('utf-8')) while True: data = sock.recv(1024) time.sleep(1) #如果客户端没有发送数据或发送’exit‘:关闭连接 if not data or data.decode('utf-8') =='exit': break sock.send(('Hello, %s'.format(data.decode('utf-8')).encode('utf-8'))) sock.close() print('Connection from %s:%s closed'.format(addr[0],addr[1])) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #绑定监听端口 s.bind(('127.0.0.1', 9999)) #开始监听: s.listen(5) #param : 等待连接的最大数量 print('waiting for connecting') while True: #接收一个新的连接: sock, addr = s.accept() #accept会等待并发返回一个客户端的连接 #使用多线程处理:单线程在处理过程中,无法接收其他客户端的连接 t = threading.Thread(target=deal_by_tcp, args=(sock,addr)) t.start() #启动线程
##TCP客户端 #导入socket库 import socket import io #创建一个socket: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1',9999)) s.send(b'Norton') #接收从服务器返回的数据: while True: d = s.recv(1024) #每次最多接收1K字节 if d: print(d.decode('utf-8')) else: break s.close()
可以发现,TCP的构建传输的交互过程更为复杂,而传输过程更为简明且具有针对性、UDP则更加“神经大条”,适合多发和对可靠性要求不高的网络。
作者: Norton和Qiume住的窝
出处:https://www.cnblogs.com/Nortonary/p/12869274.html