欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

利用Python两分钟了解TCP和UDP编程实现

程序员文章站 2022-08-09 15:34:42
TCP和UDP是OSI七层模型中传输层的两个协议,对应了两种传输方式 特点如下,更多更详细请访问:TCP与UDP的全面对比 UDP TCP 是否连接 无连接 面向连接 是否可靠 不可靠传输,不使用流量控制和拥塞控制 可靠传输,使用流量控制和拥塞控制 连接对象个数 支持一对一,一对多,多对一和多对多交 ......

tcpudposi七层模型中传输层的两个协议,对应了两种传输方式

特点如下,更多更详细请访问: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则更加“神经大条”,适合多发和对可靠性要求不高的网络。