1.什么是socket编程
网络世界基本都是TCP/IP协议进行通讯
TCP/IP协议是一种传输数据的方案
若使用requests库,发送HTTP请求消息,其实requests库底层也是使用的socket编程接口
2.python语言中的socket编程
要进行socket编程,发送网络信息,我们可以使用python内置的socket库,目前的socket编程,使用最多的就是通过TCP协议进行网络通讯,TCP通讯的双方分别为服务端和客户端,双方需要建立一个虚拟的连接,然后双方程序,才能发送业务数据信息,建立TCP虚拟连接是通过三次握手进行的。
1)服务端程序
# ============TCP 服务端程序(Linux)==================
# 导入socket库
from socket import *
# 主机地址为0.0.0.0,表示绑定本机所有网络接口IP地址
# 等待客户端来连接
IP = '10.20.152.215'
# 端口号
PORT = 50000
#定义一次从socket缓冲区最多读入512个字节数据
BUFLEN = 512
# 实例化一个socket对象,给一个类加上括号,进行实例化
# 参数AF_INET表示socket网络层使用IP协议
# 参数SOCK_STREAM表示socket传输层使用TCP协议
listenSocket = socket(AF_INET, SOCK_STREAM) # 等待客户端连接
# socket绑定IP地址和端口号
listenSocket.bind((IP, PORT))
# 使用socket处于监听状态,等待客户端的连接请求
# 参数5表示,最多接受多少个等待连接的客户端
listenSocket.listen(5)
print(f'服务端启动成功,在{PORT}端口等待客户端连接...')
dataSocket , addr = listenSocket.accept()
print('接受一个客户端连接:',addr)
while True:
# 尝试读取对方发送的消息
# BUFLEN 指定从接收缓冲里最多读取多少个字节
recved = dataSocket.recv(BUFLEN)
# 如果返回空bytes,表示对方关闭了连接
# 退出循环,结束消息收发
if not recved:
break
# 读取的字节数据是bytes类型,需要解码为字符串
info = recved.decode()
print(f'收到对方信息:{info}')
# 发送的数据类型必须是bytes,所以要编码
dataSocket.send(f'服务端接收到了信息{info}'.encode())
# 服务端也调用close()关闭socket
dataSocket.close()
listenSocket.close()
2)客户端程序
# ============TCP 客户端程序(TE)==================
# 导入socket库
from socket import *
IP = '10.20.152.215'
SERVER_PORT = 50000
BUFLEN = 512
# 实例化一个socket对象,指明协议,给一个类加上括号,进行实例化
dataSocket = socket(AF_INET,SOCK_STREAM)
# 连接服务端socket
dataSocket.connect((IP,SERVER_PORT))
while True:
# 从终端读入用户输入的字符串
toSend = input('>>>')
if toSend == 'exit':
break
# 发送消息,也要编码为bytes
dataSocket.send(toSend.encode())
# 等待接受服务端的消息
recved = dataSocket.recv(BUFLEN)
# 如果返回空bytes,表示对方关闭了连接
if not recved:
break
# 打印读取的消息
print(recved.decode())
dataSocket.close()
3.应用消息格式
实际企业开发过程中,消息往往是有格式定义的,消息的格式定义往往可以归入OSI网络模型的表示层。
比如:定义消息头、消息体
消息头存放消息的格式数据,比如长度、类型、状态等,消息体存放具体的传送数据
TCP协议传输的是字节流(bytes stream),如果消息中没有明确的消息边界,接收方不一定知道一个完整的消息从字节流的哪里开始到哪里结束。
指定消息的边界有两种形式
1)用特殊字节作为消息的结尾符号:可以用消息内容中不可能出现的字节串(如FFFFFF)作为消息的结尾字符。
2)在消息开头的某个位置,直接指定消息的长度:UDP协议通常不需要指定消息的边界,因为UDP是数据报协议,应用程序从socket接收到的必定是发送放发送的完整信息。