项目地址
https://gitee.com/lmk73444/learn_spring/tree/master/doc/1_x%E5%AD%A6%E4%B9%A0/002_py_socket
python socket试验
mkdir /root/git_proj
cd /root/git_proj
# 首次 clone 项目
git clone https://gitee.com/lmk73444/learn_spring.git
# 非首次
# 更新项目
cd /root/git_proj/learn_spring
git remote update
git checkout -f origin/master
# 进入实验目录
cd /root/git_proj/learn_spring/doc/1_x学习/002_py_socket
# 在宿主机 启动 猜数服务器
docker compose up -d
# [+] Running 3/3
# ✔ Network 002_py_socket_default Created 0.1s
# ✔ Container 002_py_socket-socket-client-1 Started 0.1s
# ✔ Container 002_py_socket-socket-server-1 Started
# 打印客户端输出
docker logs 002_py_socket-socket-client-1
# 请出拳:(0) 石头(1) 剪刀(2) 布
# 绑定 client 容器输入输出
docker attach 002_py_socket-socket-client-1
# 0
# 你出了:石头,计算机出了:石头平局请出拳:(0) 石头(1) 剪刀(2) 布
# 1
# 你出了:剪刀,计算机出了:布你赢了!请出拳:(0) 石头(1) 剪刀(2) 布
# 1
# 如果出现
# You cannot attach to a stopped container, start it first
# 重新 启动 客户端
docker compose up -d
server.py
import socketserver
import random
all_choices = ['石头', '剪刀', '布']
win_list = [['剪刀', '布'], ['布', '石头'], ['石头', '剪刀']]
#创建一个socketserver类继承socketserver模块下的BaseRequestHandler类
class MyServer(socketserver.BaseRequestHandler):
def handle(self, cwin=0,pwin=0):# 服务器端阻塞,等待客户端连接
#重写父类中的handle方法,主要实现服务端的逻辑代码,,不用写bind() listen() accept()
while True:
conn = self.request
addr = self.client_address
print(conn) #<socket.socket fd=864, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 50565)>
print(addr) #('127.0.0.1', 50565)
while True:
computer = random.choice(all_choices)
send_data=('\n请出拳:(0) 石头(1) 剪刀(2) 布')
send_data=send_data.encode()
conn.sendall(send_data)
recv_data = str(conn.recv(20480), encoding='utf8') #接收到来自客户端的数据
print(recv_data)
if recv_data == 'bye': #如果客户端发送的是‘bye’就断开连接
break
index = int(recv_data)
player = all_choices[index]
send_data = ('\n你出了:%s,计算机出了:%s' % (player, computer))
send_data = send_data.encode()
conn.sendall(send_data)
if player == computer:
send_data = ('\n\033[32;1m平局\033[0m')
send_data = send_data.encode() # 类型转换
conn.sendall(send_data) # 服务器端回复数据给客户端
elif [player, computer] in win_list:
send_data = ('\n\033[32;1m你赢了!\033[0m')
send_data = send_data.encode()
conn.sendall(send_data)
pwin += 1
else:
send_data=('\n\033[31;1m你输了!\033[0m')
send_data = send_data.encode()
conn.sendall(send_data)
cwin += 1
conn.close()
if __name__ == '__main__':
#实例化server对象,传入本机ip,以及监听的端口号,还有新建的继承socketserver模块下的BaseRequestHandler类
server = socketserver.ThreadingTCPServer(('0.0.0.0',9999),MyServer)
#激活服务端
server.serve_forever()