粘包
只有tcp协议才会发送粘包,udp不会发生。 发送端发送数据,接收端不知道应该如何去接收,造成的一种数据混乱的现象
import
subprocess
r = subprocess.Popen(‘ls‘,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
# subprocess.Popen(cmd,shell=True,subprocess.stdout,subprocess.stderr)
# cmd : 代表系统命令
# shell = True 代表这条命令是 系统命令,告诉操作系统,将cmd当成系统命令去执行
# stdout 是执行完系统命令之后,用于保存结果的一个管道
# stderr 是执行完系统命令之后,用于保存错误结果的一个管道
stdout = r.stdout.read().decode(‘gbk‘)
stderr = r.stderr.read().decode(‘gbk‘)
print(‘正确的返回结果:‘,stdout)
print(‘错误的返回结果:‘,stderr)
print(‘错误的返回结果:‘,stderr)
客户端发送要执行命令
服务器执行,执行完将结果返回给客户端
客户端拿到结果呈现到用户眼前
服务端
import
socket
import
subprocess
sk = socket.socket()
sk.bind((‘127.0.0.1‘, 8080))
sk.listen()
conn, addr = sk.accept()
while 1:
cmd = conn.recv(1024).decode(‘utf-8‘)
r = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout = r.stdout.read()
stderr = r.stderr.read()
if stderr:
conn.send(stderr)
else:
conn.send(stdout)
conn.close()
sk.close()
客户端
import
socket
sk = socket.socket()
sk.connect_ex((‘127.0.0.1‘, 8080))
while 1:
cmd = input(‘请输入一个命令>>>‘)
sk.send(cmd.encode(‘utf-8‘))
result = sk.recv(102)
result = result.decode(‘gbk‘)
print(result)
sk.close()
socket 实现 ssh
a = ‘邹‘print(len(a)) # 1print(len(a.encode())) # 3 转换为bytes一个汉字三个字符
客户端
import
socket
client = socket.socket()
client.connect((‘localhost‘, 9999))
while True:
msg = input(">>:").strip()
if len(msg) == 0: # 输入的为空continue
client.send(msg.encode("utf-8"))
data = client.recv(1024)
print("recv:", data.decode())
client.close()
服务端
import
socket, os
server = socket.socket()
server.bind((‘localhost‘, 9999))
server.listen()
while True:
conn, addr = server.accept()
print(‘new conn‘, addr)
while True:
data = conn.recv(1024)
ifnot data:
print(‘客户端已断开‘)
breakprint(‘执行指令:‘, data)
cmd_res = os.popen(data.decode()).read() # 执行输入的命令,decode转换为字符串if len(cmd_res) == 0:
cmd_res = ‘cmd has no out‘
conn.send(cmd_res.encode(‘utf-8‘)) # 转为utf-8发过去
当我们在客户端执行 ifconfig 命令时,第一次返回的不全(1024字节),在执行 ls 命令时,返回的是 ifconfig 剩下的命令(1024字节),如下
>>:ifconfig recv: lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384 options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP> inet 127.0.0.1 netmask 0xff000000 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 nd6 options=201<PERFORMNUD,DAD> gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280 stf0: flags=0<> mtu 1280 ap1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1500 options=400<CHANNEL_IO> ether b2:9c:4a:c4:34:e7 media: autoselect status: inactive en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 options=400<CHANNEL_IO> ether 90:9c:4a:c4:34:e7 inet6 fe80::18f2:9b2f:4496:675e%en0 prefixlen 64 secured scopeid 0x6 inet 192.168.31.110 netmask 0xffffff00 broadcast 192.168.31.255 nd6 options=201<PERFORMNUD,DAD> media: autoselect status: active p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304 options=400<CHANNEL_IO> ether 02:9c:4a:c4:34:e7 media: autoselect status: inactive awdl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1484 opti >>:ls recv: ons=400<CHANNEL_IO> ether e2:3f:ba:ac:28:1d inet6 fe80::e03f:baff:feac:281d%awdl0 prefixlen 64 scopeid 0x8 nd6 options=201<PERFORMNUD,DAD> media: autoselect status: active llw0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 options=400<CHANNEL_IO> ether e2:3f:ba:ac:28:1d inet6 fe80::e03f:baff:feac:281d%llw0 prefixlen 64 scopeid 0x9 nd6 options=201<PERFORMNUD,DAD> media: autoselect status: active en2: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500 options=460<TSO4,TSO6,CHANNEL_IO> ether 1e:66:6c:14:0d:c4 media: autoselect <full-duplex> status: inactive en1: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500 options=460<TSO4,TSO6,CHANNEL_IO> ether 1e:66:6c:14:0d:c5 media: autoselect <full-duplex> status: inactive en3: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500 options=460<TSO4,TSO6,CHANNEL_IO> ether 1e:66:6c:14:0d:c1 media: autoselect <full-duplex> status: inactive en4: flags=8963<U
全部接收
先判断需要接收的数据,然后接收的和实际的对比,如果小于实际的,继续接收,否则,打印出接收的大小和命令
客户端
import
socket
client = socket.socket()
client.connect((‘localhost‘, 9999))
while True:
msg = input(">>:").strip()
if len(msg) == 0:
continue
client.send(msg.encode("utf-8"))
data_size = client.recv(1024) # 接收命令的长度print(‘需要接收的数据大小:‘, data_size)
client.send(‘开始发吧‘.encode(‘utf-8‘)) # 处理黏包
reve_size = 0
reve_data = b‘‘while reve_size < int(data_size.decode()): # data_size是byte类型
data = client.recv(1024)
reve_size += len(data) # 每次收到的有可能小于1024,所以必须用len判断
reve_data += data
else:
print(‘接收到的大小:‘, reve_size)
print(reve_data.decode())
client.close()
服务端
import
socket, os
server = socket.socket()
server.bind((‘localhost‘, 9999))
server.listen()
while True:
conn, addr = server.accept()
print(‘new conn‘, addr)
while True:
print(‘等待新指令‘)
data = conn.recv(1024)
ifnot data:
print(‘客户端已断开‘)
breakprint(‘执行指令:‘, data)
cmd_res = os.popen(data.decode()).read() # 执行输入的命令,decode转换为字符串print(‘数据的大小:‘, len(cmd_res))
if len(cmd_res) == 0:
cmd_res = ‘cmd has no out‘
conn.send(str(len(cmd_res.encode())).encode(‘utf-8‘)) # 数字不能encode。cmd_res.encode()将汉字转换成3个字节,不转发送的大小和接收的大小不一样
conn.recv(1024) # 处理黏包
conn.send(cmd_res.encode(‘utf-8‘)) # 转为 utf-8发过去
原文:https://www.cnblogs.com/zouzou-busy/p/13771403.html
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!