周知,基于TCP协议的套接字服务端不能实现:多个客户端并发访问一个服务端,必须一个链接关闭后,才能建立新的链接;
所以,socketserver可以实现并发;
下面简单写一个远程执行shell命令的服务端、客户端
这里只需改写一下服务端:
import socketserver
import subprocess
class MyServer(socketserver.BaseRequestHandler):
def handle(self):
print("conn is:",self.request)
print("addr is:",self.client_address)
#通信循环
while True:
try:
#收消息
cmd_msg=self.request.recv(1024*8)
print("收到客户端的消息:",cmd_msg.decode("utf-8"))
res=subprocess.Popen(cmd_msg.decode("utf-8"),shell=True,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
#发消息(将收到的消息原封不动发回去)
err=res.stderr.read()
if err:
cmd_res = err
else:
cmd_res = res.stdout.read()
#将执行结果发送至客户端
self.request.sendall(cmd_res)
except Exception:
break
if __name__ == '__main__':
# ThreadingTCPServer:表示多线程TCP协议服务端,参数两个(<ip+端口号>tuple,刚刚建立的类的名称)
#得到一个对象,命名;s
s=socketserver.ThreadingTCPServer(("127.0.0.1",8080),MyServer)
#serve_forever():表示永远服务,相当于链接循环
s.serve_forever()
客户端还是同socket编程一样:
from socket import *
tcp_socket_client=socket(AF_INET,SOCK_STREAM)
ip_port=('127.0.0.1',8080)
buffer_size=1024*8
tcp_socket_client.connect(ip_port)
while True:
cmd=input(">>>:请输入命令:").strip()
if not cmd :continue
if cmd=="quit":break
tcp_socket_client.send(cmd.encode("utf-8"))
cmd_res=tcp_socket_client.recv(buffer_size)
if not cmd_res:#cmd_res,执行成功了,但是没有返回值的情况
print("执行成功!",cmd_res.decode("gbk"))
else:
print(cmd_res.decode("gbk"))#系统默认编码:gbk