一. 基于tcp协议通信的套接字(通信循环+链接循环)
服务端代码
from socket import *
server = socket(AF_INET, SOCK_STREAM)
server.bind(('127.0.0.1', 8080))
server.listen(5)
# 链接循环
while True:
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()
客户端代码
from socket import *
client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8080))
# 通信循环
while True:
msg=input('>>: ').strip()
if len(msg) == 0:continue
client.send(msg.encode('utf-8'))
data=client.recv(1024)
print(data)
client.close()
二. 远程执行命令的程序
服务端代码
from socket import *
import subprocess
server = socket(AF_INET, SOCK_STREAM)
server.bind(('127.0.0.1', 8080))
server.listen(5)
# 链接循环
while True:
conn, client_address = server.accept()
print(client_address)
# 通信循环
while True:
try:
cmd = conn.recv(1024)
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()
客户端代码
from socket import *
client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8080))
# 通信循环
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('gbk'))
client.close()
三. 模拟ssh实现远程执行命令(解决粘包问题)
服务端代码
from socket import *
import subprocess, json, struct
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)
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()
# 1. 先制作报头
header_dic = {
'filename': 'a.txt',
'md5': 'asdfasdf123123x1',
'total_size': len(stdout) + len(stderr)
}
header_json = json.dumps(header_dic)
header_bytes = header_json.encode('utf-8')
# 2. 先发送4个bytes(包含报头的长度)
conn.send(struct.pack('i', len(header_bytes)))
# 3 再发送报头
conn.send(header_bytes)
# 4. 最后发送真实的数据
conn.send(stdout)
conn.send(stderr)
except ConnectionResetError:
break
conn.close()
server.close()
客户端代码
from socket import *
import struct,json
client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8081))
# 通信循环
while True:
cmd=input('>>: ').strip()
if len(cmd) == 0:continue
client.send(cmd.encode('utf-8'))
#1. 先收4bytes,解出报头的长度
header_size=struct.unpack('i',client.recv(4))[0]
#2. 再接收报头,拿到header_dic
header_bytes=client.recv(header_size)
header_json=header_bytes.decode('utf-8')
header_dic=json.loads(header_json)
print(header_dic)
total_size=header_dic['total_size']
#3. 接收真正的数据
cmd_res=b''
recv_size=0
while recv_size < total_size:
data=client.recv(1024)
recv_size+=len(data)
cmd_res+=data
print(cmd_res.decode('gbk'))
client.close()