socket单对单通讯
socket是Python内建库之一,用途就是网络通讯。作为实验,我们考虑两个Python程序之间的通讯,一个作为服务器,一个作为客户端,客户端向服务器发送一串字符,服务器收到后将原字符串大写后传回,直到客户端发送空信息,服务器退出。
服务器端代码:
import socket
ip_port = ('', 8888) # 这个tuple的第一项是ip地址,第二项是端口
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 定义socket类型,网络通信,TCP
s.bind(ip_port) # 套接字绑定ip和端口
s.listen(1) # 开始监听连接请求
conn, addr = s.accept() # 接受连接请求,conn是一个新的套接字,addr是客户端地址
conn.sendall('Hello from the server!'.encode('utf-8')) # 发送打招呼信息,并且用utf-8编码
while True:
try:
data = conn.recv(1024).decode('utf-8') # 接受数据并使用utf-8解码
if not data:
break # 如果数据为空就退出
conn.sendall(data.upper().encode('utf-8')) # 把数据大写后返回
except Exception as e: # 如果数据传输出错
print(e)
exit(1)
conn.close() # 关闭套接字
客户端代码:
import socket
ip_port = ('localhost', 8888) # 服务器ip和端口
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 定义socket类型,网络通信,TCP
try:
s.connect(ip_port) # 尝试连接服务器
except Exception as e: # 如果连接失败socket.socket.connect会抛出错误
print(e)
exit(1)
data = s.recv(1024).decode('utf-8') # 接受服务器的问候
print(data)
while True:
try:
msg = input('>>> ') # 此时用户可以在运行客户端的控制台中输入内容
s.sendall(msg.encode('utf-8')) # 将消息发送
if not msg:
break # 如果数据为空就退出
data = s.recv(1024).decode('utf-8') # 接受服务器的结果
print(data)
except Exception as e: # 如果数据传输出错
print(e)
exit(1)
s.close() # 关闭套接字
运行结果:
socketserver多对一通讯
由于我的目的是打算写一个联机对战游戏,那么一个服务器需要同时和多个(至少是两个)客户端建立连接。一个很容易想到的做法就是服务器多线程。好在Python已经帮我们封装好了多线程和socket库——socketserver库。
socketserver库的用法和socket几乎一模一样,而且由于只有服务器端需要多线程,所以只需要更改server.py即可。
下面是server.py的代码:
import socketserver
ip_port = ('', 10888)
class MyServer(socketserver.BaseRequestHandler):
def handle(self): # 重写RequestHandler中的handle方法用来处理请求
print("conn is :", self.request) # conn
print("addr is :", self.client_address) # addr
self.request.sendall('Hello from the server!'.encode('utf-8'))
while True: # 处理方面的逻辑都是一样的
try:
data = self.request.recv(1024).decode('utf-8')
if not data:
break
self.request.sendall(data.upper().encode('utf-8'))
except Exception as e:
print(e)
break
print("disconnected with", self.client_address)
if __name__ == '__main__':
s = socketserver.ThreadingTCPServer(ip_port, MyServer) # 建立TCP协议套接字
# 使用s.serve_forever()接受无穷次连接(需要按下Ctrl+C中断)
# 也可以使用一次s.handle_request()接受一次连接
s.serve_forever()
运行结果:
服务器内部数据传输
现在我们已经解决了服务器和客户端之间的数据传输问题了,但是这又引入了新的问题:服务器用多线程和客户端交流,但是socketserver封装的太好了,想要直接从外部操作各个线程显然不显示,那么如何进行服务器各个线程之间的交流呢?
请听下回分解……
😀
–601b31d481ac0ffb36c20bb7a4ceb023–