Python网络通讯主要是C/S架构的,采用套接字实现。C/S架构是客户端(Client)和服务端(Server)架构,Server唯一的目的就是等待Client的请求,Client连上Server发送必要的数据,然后等待Server端完成请求的反馈。
C/S网络编程:
Server端进行设置,首先创建一个通信端点,让Server端能够监听请求,之后就进入等待和处理Client请求的无限循环中。Client编程相对Server端编程简单,只要创建一个通信端点,建立到服务器的链接,就可以提出请求了。
tcp 与 udp
tcp:通信之前一定要建立一条连接,要创建TCP套接字就得创建时指定套接字类型为SOCK_STREAM。
udp:无需建立连接就可以通讯,要创建UDP套接字就得创建时指定套接字类型为SOCK_DGRAM。
套接字
套接字是一种具有之前所说的“通信端点”概念的计算网络数据结构,网络化的应用程序在开始任何通信都必须创建套接字。Python支持:AF_UNIX、AF_NETLINK、AF_INET,其中AF_INET是基于网络的套接字。
# 使用socket模块的socket()函数来创建套接字
socket(socket_family, socket_type, protocol=0)
# socket_family:AF_UNIX、AF_INET
# socket_type可:SOCK_STREAM、SOCK_DGRAM
# protocol一般不填,默认值是0
# 创建一个TCP/IP套接字
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 创建一个UDP/IP套接字
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
from socket import *
# socket对象中有太多属性,可以大幅缩短代码,调用如下
tcpSock = socket(AF_INET, SOCK_STREAM)
服务器端套接字函数
# 绑定地址(主机号、端口号对)到套接字
s.bind()
# 开始 tcp 监听
s.listen()
# 被动接受 tcp 客户端连接,(阻塞式)等待连接的到来
s.accept()
客户端套接字函数
# 主动初始化 tcp 服务器连接
s.connect()
# connect() 函数扩展版本,出错时返回出错码而不是抛出异常
s.connect_ex()
公共用途的套接字函数
# 接受 tcp 数据
s.recv()
# 发送 tcp 数据
s.send()
# 完整发送 tcp 数据
s.sendall()
# 接受 udp 数据
s.recvfrom()
# 发送 udp 数据
s.sendto()
# 连接到当前套接字的远端地址(tcp 连接)
s.getpeername()
# 获取当前套接字的地址
s.getsockname()
# 返回指定套接字的参数
s.getsockopt()
# 设置指定套接字的参数
s.setsockopt()
# 关闭套接字
s.close()
面向模块的套接字函数
# 设置套接字的阻塞与非阻塞模式
s.setblocking()
# 设置阻塞套接字操作的超时时间
s.settimeout()
# 得到阻塞套接字操作的超时时间
s.gettimeout()
面向文件的套接字函数
# 套接字的文件描述符
s.fileno()
# 创建一个与套接字关联的文件对象
s.makefile()
注意
python3.5和Python2.7在套接字返回值解码上有区别:
python bytes和str两种类型可以通过函数encode()和decode()相互转换,
str→bytes:encode()方法。str通过encode()方法可以转换为bytes。
bytes→str:decode()方法。要把bytes变为str,就需要用decode()方法。
而如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。
服务器端
# tcpSerSock.py
from socket import *
from time import ctime
HOST = ‘localhost‘ # 主机号
PORT = 21567 # 端口号
BUFSIZE = 1024 # 缓冲区大小为 1k
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR) # 绑定地址到套接字
tcpSerSock.listen(5) # 监听,最多监听 5 个连接
while True: # 无线循环等待连接
try:
print(‘Waiting for connection....‘)
tcpCliSock, addr = tcpSerSock.accept() # 被动接受客户端连接
print(‘Connected client from: ‘, addr)
while True:
data = tcpCliSock.recv(BUFSIZE).decode() # 接收数据
if not data:
break
else:
print(‘Client:‘, data)
time_data = ‘[%s] %s‘%(ctime(), data)
tcpCliSock.send(time_data.encode()) # 发送时间戳
except Exception as e:
print(‘Error: ‘, e)
tcpSerSock.close() # 关闭服务器
tcpCliSock.close()
客户端
# tcpCliSock.py
from socket import *
HOST = ‘localhost‘ # 服务器主机号
PORT = 21567 # 服务器端口号
BUFSIZE = 1024 # 缓冲区大小为 1k
ADDR = (HOST, PORT)
tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR) # 连接服务器
while True: # 无限循环等待连接
try:
data = input(‘>‘).encode()
if not data:
break
tcpCliSock.send(data) # 发送数据
data = tcpCliSock.recv(BUFSIZE).decode() # 接受数据
if not data:
break
print(‘Server: ‘, data)
except Exception as e:
print(‘Error: ‘, e)
tcpCliSock.close() # 关闭客户端
开始通信
# Server
‘‘‘
Waiting for connection....
Connected client from: (‘127.0.0.1‘, 51744)
Client: hello
Client: i am shivers
Waiting for connection....
‘‘‘
# Client
‘‘‘
>hello
Server: [Sun Feb 14 16:25:23 2021] hello
>i am shivers
Server: [Sun Feb 14 16:25:30 2021] i am shivers
>
‘‘‘
原文:https://www.cnblogs.com/shivers0x72/p/14402135.html