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

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则更加“神经大条”,适合多发和对可靠性要求不高的网络。

posted @ 2020-05-11 15:06  neumy  阅读(324)  评论(0编辑  收藏  举报