这两个协议都是传输层
的协议,解决的问题,都是端口与端口的通信问题。
TCP 每次建立通信,都需要三次握手
,确定双方状态完毕,在发送数据。如果发送的数据出现了异常,TCP 也内置了一些处理的机制,确保了数据能准确到达目的地。
UDP 只负责把数据发送到指定的地址,其他的问题,是否收到,数据接受的情况是否完整,全部不管。
它们两者有不同的应用场景,概括起来就是 TCP 可靠,但是效率低,而 UDP 不可靠,但是效率高。
socket
是操作系统一种通信接口,大部分的编程语言都支持 socket
编程。有了这个接口,我们就能处理协议的工作: TCP
、 UDP
、 HTTP
...
通常,通信的双方会有一端是 服务端
,另一个端是 客户端
。就像你目前访问 JMJC.TECH
,简明教程作为服务端接受并处理用户的多个请求。
server.py
import socket
# socket.AF_INET (IPV4)
# socket.SOCK_STREAM (TCP)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 监听 IP:port
s.bind(('127.0.0.1', 9999))
# 最大允许连接数量
s.listen(3)
# 死循环,重复的处理着每个客户端的请求
while True:
# 阻塞 每当有客户端的请求过来开始执行
# 连接处理 (已完成三次握手)并获取资源对象 | conn 请求对象 | addr 客户端地址 ip: port
conn, addr = s.accept()
# 请求处理 | 读取客户端发送过来的数据 | recv(1024) 指定每次读取 1024 字节,当数据较长时可以通过 while 循环读取
data = conn.recv(1024).decode('utf-8')
# 响应处理 | 把客服端发送过来的数据又转发回去
conn.sendall(data.encode('utf-8'))
# 关闭客户端连接
conn.colse()
client.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接服务端
s.connect(('127.0.0.1', 9999))
# 请求 | 发送数据到服务端
s.sendall(b'hello')
# 响应 | 接受服务端返回到数据
data = s.recv(1024)
print(data) # hello
# 关闭 socket
s.close()
上面的 TCP
服务器,每次只能处理一个客户端的请求,当有多个客户端同时请求时,会排成一个列队,处理完一个在处理下一个。我们可以利用多任务章节的知识 (进程和线程、异步 )稍微的给服务器做一点修改。
import socket
import threading
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 9998))
s.listen(3)
# 处理函数
def link(conn, addr):
data = conn.recv(1024).decode('utf-8')
conn.sendall(data.encode('utf-8'))
conn.close()
while True:
conn, addr = s.accept()
# 每次新开一个线程,处理客户端的请求
t = threading.Thread(target=link, args=(conn, addr))
t.start()