之前简单介绍了tcp和udp的服务端和客户端,但一个完整的服务端必须至少满足三个功能
(1)绑定一个固定的ip和port
(2)一直对外提供服务,稳定运行
(3)能够支持并发
一、通信循环
对于客户端与服务端,不单单只能交流一次,正常需要交流多次,这时候需要支持通信循环,用while循环实现多次交流
服务端:
from socket import * server = socket(AF_INET, SOCK_STREAM) server.bind((‘127.0.0.1‘, 8080)) server.listen(5) conn, client_addr = server.accept() # 通信循环 while True: data = conn.recv(1024) conn.send(data.upper()) conn.close() server.close()
客户端:
from socket import * client = socket(AF_INET, SOCK_STREAM) client.connect((‘127.0.0.1‘, 8080)) # 通信循环 while True: msg=input(‘>>: ‘).strip() client.send(msg.encode(‘utf-8‘)) data=client.recv(1024) print(data) client.close()
二、链接循环
单单一个服务端和客户端交流是不够的,需要多个客户端可以与链接循环
三、bug处理
(1)起因:当客户端非正常的断开,服务端就会报错,可预知但无法准确知道。
(2)起因:客户端输入了空,服务端不会收到空数据;如果服务端收到了空数据,肯定是客户端单方面的把链接异常中断掉,而在在windows系统上服务端就会抛出异常,在Linux系统上服务端recv一直收空,无法预知异常发生的条件
解决方法:异常处理try...except
from socket import * server = socket(AF_INET, SOCK_STREAM) server.bind((‘127.0.0.1‘, 8080)) server.listen(5) conn, client_addr = server.accept() print(client_addr) # 通信循环 while True: try: data = conn.recv(1024) if len(data) == 0:break # 针对linux系统 print(‘-->收到客户端的消息: ‘,data) conn.send(data.upper()) except ConnectionResetError: break conn.close() server.close()
为了执行系统命名,服务端需要导入subprocess模块
server = socket(AF_INET, SOCK_STREAM) server.bind((‘127.0.0.1‘, 8081)) server.listen(5) # 链接循环 while True: conn, client_addr = server.accept() print(client_addr) # 通信循环 while True: try: cmd = conn.recv(1024) #cmd=b‘dir‘ if len(cmd) == 0: break # 针对linux系统 obj=subprocess.Popen(cmd.decode(‘utf-8‘), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) stdout=obj.stdout.read() stderr=obj.stderr.read() print(len(stdout) + len(stderr)) conn.send(stdout+stderr) except ConnectionResetError: break conn.close() server.close()
原文地址:https://www.cnblogs.com/ye-hui/p/9911736.html
时间: 2024-11-02 04:24:04