一、python中的socket编程
对于现代应用程序来说,只要是网络程序,都是调用了socket编程接口才将消息通过网络发送出去的。一些http库中已经包含了socket接口,可以在编写程序时直接调用库函数,但有时程序不用http协议时,就不得不使用socket编程接口自己构建消息传送格式。python中内置有socket库,可直接使用库函数进行常见协议的socket编程
二、使用TCP协议的socket编程
目前的socket编程,使用最多的就是通信双方使用tcp协议(通信双方分为服务器和客户端,通信双方需要先通过三次握手建立虚拟连接,然后才能传送信息)进行通信。
以下是一个通过TCP协议进行通信的客户端和服务端程序。
①TCP 服务端程序
# === TCP 服务端程序 server.py ===# 导入socket 库(*表示导入所有可用函数和名字)from socketimport*# 变量名字大写通常表示配置项# [socket编程常用的配置项:IP地址、端口号、缓冲区长度(BufferLength)]# 主机地址为空字符串,表示本机所有可用的ip地址# 客户端和服务端在同一台机器上,可用‘0.0.0.0’(不清楚IP地址)或‘127.0.0.1’(本机环回地址)# 等待客户端来连接
IP=''# 端口号
PORT=50000# 定义一次从socket缓冲区最多读入512个字节数据
BUFLEN=512# socket是库中的一个类,有两个初始化参数(分别指明这个socket所用的传输层和网络层协议)# 类后加括号实例化一个socket对象,赋给监听socket(因为这是一个服务端程序,要等待客户端的连接)# 参数 AF_INET (internet)表示该socket网络层使用IP协议# 参数 SOCK_STREAM (一种流)表示该socket传输层使用tcp协议
listenSocket= socket(AF_INET, SOCK_STREAM)# 调用socket类的bind()函数,绑定ip地址和端口,即与服务器连接的ip地址和端口号# 参数是(IP地址,端口号)二元组
listenSocket.bind((IP, PORT))# 调用socket类的listen()函数,使socket处于监听状态,等待客户端的连接请求# 参数 8 表示 最多接受多少个等待连接的客户端(类似在排队的人数)
listenSocket.listen(8)print(f'服务端启动成功,在{PORT}端口等待客户端连接...')# 此时,如果有客户端发来连接请求,就调用accept()函数连接客户端# 若没有连接请求,服务端程序在此处于阻塞(睡眠)状态# =================================part 1 =====================================# accept()函数有两个返回值:# 一个是一个新的socket对象,一个是连接它的客户端的地址(包括IP地址和端口号)# 可以将地址打印出来
dataSocket, addr= listenSocket.accept()print('接受一个客户端连接:', addr)# while循环的作用:不断接收客户端发来的消息whileTrue:# 调用数据socket的recv()方法,recieve(接收),# 参数BUFLEN 指定从接收缓冲里最多读取多少字节# 这里的recvd接受的是字节串(bytes类型),与字符串(string类型)不同,网络传输用的都是字节串
recved= dataSocket.recv(BUFLEN)# 如果返回空bytes(空字节),表示对方关闭了连接# 退出循环,结束消息收发ifnot recved:break# 读取的字节数据是bytes类型,需要调用bytes对象的decode()方法解码为字符串# 也有可能是音频数据、图像数据...有不同解码方式
info= recved.decode()print(f'收到对方信息: {info}')# 服务端也给客户端回一句话,把发来的信息再发回去hhh# 发送的数据类型必须是bytes,所以要编码
dataSocket.send(f'服务端接收到了信息 {info}'.encode())# =================================part 2 =====================================# 服务端也调用close()关闭socket
dataSocket.close()
listenSocket.close()# =================================part 3 =====================================
②TCP 客户端程序
# === TCP 客户端程序 client.py ===# 引入socket库from socketimport*#配置项:客户端要访问的IP地址(此处是本机)、服务端程序端口号、客户端缓冲区长度
IP='127.0.0.1'
SERVER_PORT=50000
BUFLEN=1024# 实例化一个socket对象,命名为‘数据传输接口’(因为是客户端)# 指明协议(客户端与服务器所用通信协议必须一致)
dataSocket= socket(AF_INET, SOCK_STREAM)# 调用connect()(参数为服务端程序的IP和PORT)连接服务端正在等待的listen_socket# 此时操作系统底层就向服务端发送三次握手的第一个报文了# 之后服务端的concept()底层和客户端的connect()底层就开始进行三次握手
dataSocket.connect((IP, SERVER_PORT))# =================================part 1 =====================================whileTrue:# 从终端读入用户输入的字符串
toSend=input('>>> ')if toSend=='exit':break# 发送消息,也要编码为 bytes
dataSocket.send(toSend.encode())# 等待接收服务端的消息# 如果等不到就停在这里不动了
recved= dataSocket.recv(BUFLEN)# 如果返回空bytes,表示对方关闭了连接ifnot recved:break# 打印读取的信息print(recved.decode())
dataSocket.close()# =================================part 2 =====================================
注意:
运行时先运行服务端程序,再运行客户端程序。
两个程序不要在同一个idle中运行。