python socket 套接字编程 单进程服务器 实现多客户端访问

时间:2023-03-08 20:29:33

服务器:

 import socket
#单进程服务器 实现多客户端访问 IO复用
#吧所有的客户端套接字 放在一个列表里面,一次又一次的便利过滤
#这就是apache: select模型 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #设置端口复用
#AF_INET: IPV4
#AF_INET6: IPV6
#SOCK_STREAM: TCP
#SOCK_DGRAM: UDP
Host = ''
port = 23333
server.bind((Host,port))
#服务器绑定端口 8080
server.listen(5)
#服务器同时监听5个 最大链接数 5 print('[+] server open') c_server = {}
#定义一个全局字典
server.setblocking(0)
#设置服务器recv接受信息和send发送信息为非阻塞状态(默认为阻塞状态)
#是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错。
while True:
try:
try: client,c_addr = server.accept() except BlockingIOError:
#无法立即完成一个非阻止性套接字操作。
if not c_server:
#如果字典为空
continue
#重新接收套接字
pass
else:
client.setblocking(0)#设置套接字属性为非阻塞
#是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错。
#[WinError 10035] 无法立即完成一个非阻止性套接字操作。
c_server[client] = c_addr#以字典形式存储新链接的套接字
print('[+] from',c_addr)
for a in list(c_server.keys()):
#这里将字典的keys取出来 在列表化,在没有信息的时候删除套接字了
try:
msg = a.recv(1024).decode('utf-8')
#非阻塞接受消息,但是如果客户端不马上发送,就会报错,所以设置一个延迟接收
except BlockingIOError as e:
continue if not msg:
print('[%s] closed'%(c_server[a][0]))
a.close()
del c_server[a]
continue
print("来自%s的消息: %s"%(c_server[a][0],msg))
a.send(msg.encode('utf-8'))
#发送重复的消息
except KeyboardInterrupt:
break server.close()

客户端:

 #coding:utf-8

 import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#创建一个客户端链接,socket.AF_INET代表ipv4,socket.SOCK_STREAM代表tcp套接字
client.connect(('127.0.0.1',23333))
#客户端链接
print('[+] 链接成功')
#链接成功显示
while True:
msg = input('>>>')
if msg == 'quit':
#如果输入的信息是quit 就退出链接
break
if len(msg) == 0:#如果直接输入的一个回车的话
#就重新输入,因为不能发送空 ,发送空的花 客户端会卡住
continue
client.send(msg.encode('utf-8'))
#客户端发送信息msg 以utf8格式发送数据
data = client.recv(1024).decode('utf-8')
if not data:
#如果数据为空/0
#服务器主动断开s
break
print('[+] 服务器主动断开了链接......') print('服务器发来:',data) print('[+] 链接关闭...') client.close()

服务器就是apache: select模型