版本一
服务端
# coding=utf-8 import socket import os server = socket.socket() server.bind(("localhost",6969)) server.listen() print("Waiting for SSH conn....") while True: conn,addr = server.accept() print("New conn:",addr) while True: print("Waiting new cmd...") data = conn.recv(1024) if not data: print("Client has lost..") break print("执行cmd:",data) cmd_res = os.popen(data.decode()).read() print("before send:",len(cmd_res)) if len(cmd_res) == 0: cmd_res = "cmd has no outpt." conn.send(cmd_res.encode("utf-8")) print("send done") server.close()
客户端
# coding=utf-8 import socket client = socket.socket() client.connect(("localhost",6969)) while True: cmd = input(">>:").strip() if len(cmd) == 0: continue client.send(cmd.encode("utf-8")) cmd_res = client.recv(1024) print(cmd_res.decode()) client.close()
存在问题:
服务端一次只发送1024,如果客户端执行命令结果大于1024,则会存入缓冲区,等待下一次客户端执行命令时,发送上一次未发送完的命令结果
如图:
1、客户端执行指令:ipconfig /all
2、服务端显示发送数据大小为2428,已大于1024
3、客户端再次执行dir,但收到的数据仍为ipconfig /all的数据
版本二
服务端
要解决上面的问题,只需在服务端向客户端发送正式数据前,先统计数据大小,并告知客户端数据大小,再由客户端进行判断,收到的数据如果小于该数据大小,便循环收取数据
客户端
客户端需要增加接受数据总大小,并进行判断,来循环接受
如图,已全部接收
解决粘包问题
在Linux中运行时,由于两次conn.send连在一起执行,会导致首次发出的包总大小数据和正式返回的数据连在一起,导致客户端报错,程序退出,解决该问题只需在两次send中间加一个ack确认即可
服务端
客户端
测试: