ssh:客户端连接上服务器后,让服务器执行命令,返回给客户端。
服务端:
import socket,os server = socket.socket() server.bind(("localhost", 6969)) server.listen(5) while True: conn, addr = server.accept() print("new conn:", addr) while True: data = conn.recv(1024) if not data: break print("执行指令:", data) cmd = os.popen(data.decode()).read() #popen()接收字符串,返回也是字符串类型 print("before send:",len(cmd.encode())) if len(cmd)==0: cmd="cmd has no output" conn.send(str(len(cmd.encode())).encode()) #str()将一个数值转换为字符串 client_aut=conn.recv(1024) print("authentor form client",client_aut.decode()) conn.send(cmd.encode()) server.close()
客户端:
import socket client=socket.socket() client.connect(("localhost",6969)) while True: cmd=input(">>:").strip() if len(cmd)==0: continue client.send(cmd.encode()) rec_cmd_size=client.recv(1024) #每次接收可能不是1024,总之,服务端发多少,客户端收多少 print("接收到的命令结果原大小:",rec_cmd_size) client.send("已经准备好接收,server可发送".encode()) rec_size=0 rec_data=b'' while rec_size < int(rec_cmd_size.decode()): data=client.recv(1024) rec_size+=len(data) rec_data+=data else: print("cmd has received done",rec_size) print(rec_data.decode()) client.close()
注:(1)若有两次或多次send连续,则会出现粘包的问题。原因:可能一次发送的数据多于1024,多出来的数据发送不了就会存储在缓冲区,这样导致第二次send时发送的是第一次遗留的数据,也可能是第一次遗留数据与第二次的混合。解决办法:send间加交互(如上程序中有写)使得两次数据不合并。
(2)send()必须发送字节类型数据。recv()接收到的也是字节类型数据。字节数据decode成字符串数据,字符串encode后为字节数据。
(3)ConnectionRefusedError: [WinError 10061] 由于目标计算机积极拒绝,无法连接。此错误是由于ip地址,端口有问题导致。
(4)客户端设置命令原长度与接收长度的原因是验证是否能完成接收,还有因为每次接收可能不是1024,测试每次接收的数据量。