远程-粘包现象

远程执行命令

远程执行命令 : 在客户端输入一个命令,通过网络传输给服务器,服务器后端运行此命令得到结果,将结果通过网络传输返回给客户端


subprocess模块
import subprocess
obj = subprocess.Popen('dir',         #命令
                       shell = True,
                       stdout = subprocess.PIPE,
                       stderr = subprocess.PIPE
                       )
print(obj.stdout.read().decode('gbk'))    #正确命令
print(obj.stderr.read().decode('gbk'))    #错误命令

#shell :命令解释器,相当于调用cmd执行指定的命令
#stdout:正确结果丢到一个管道当中
#stderr:错了丢到另一个管道当中
#windows操作系统的默认编码是gbk

 

# 服务端:
import socket
import subprocess
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('127.0.0.1',10086))
server.listen(5)
while 1:
    conn, addr = server.accept()  # 等待客户端连接
    while 1:
        try:
            cmd = conn.recv(1024).decode('utf-8')  # 最大接受的字节数
            # 接受命令
            obj = subprocess.Popen(
                cmd,
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
            right_msg = obj.stdout.read()
            error_msg = obj.stderr.read()
            # 通过subprocess或者执行命令的结果
            print(right_msg,error_msg)
            conn.send(right_msg + error_msg)  # gbk 的bytes
            # 将结果发送给客户端
        except Exception:
            break
    conn.close()
server.close()

 

# 客户端
import socket

client = socket.socket()
client.connect(('127.0.0.1',10086))
while 1 :
    cmd = input('>>>').strip()
    client.send(cmd.encode('utf-8'))
    result = client.recv(1024)
    print(result.decode('gbk'))
client.close()

粘包现象

粘包现象1:

客户端发送一段数据,recv时只收了一小部分,客户端下次再接收的时候还是从缓冲区拿上次遗留的数据,产生粘包

远程-粘包现象

 

客户端 ---send()命令---> 客户端缓冲区 ---网络---> 服务端缓冲区 ---recv----> 服务端
服务端会执行客户端发送的命令,例如得到1254个字节

服务端 ---send()---> 服务端缓冲区 ---网络---> 客户端缓冲区 ---recv----> 客户端
客户端只接收1024个字节,还会剩下230个字节留在客户端缓冲区

等到下一次再次输入命令时,客户端最后接收的只有230个字节,没有本次执行命令的结果

原因:只要客户端将数据send除去,就会立马进入recv状态 会直接打印在客户端缓冲区的230个字节,而不会等到本次的命令走完整个流程

粘包现象2:

如果连续快速的发送几次少量的数据,那么服务端会一次接受完毕.

# 服务端:

import socket

server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('127.0.0.1',10086))
server.listen(5)
conn,addr = server.accept()    
data1 = conn.recv(1024)    
print(data1)
data2 = conn.recv(1024)   
print(data2)
conn.send(b'taibai')
conn.close()
server.close()
# 客户端:

import socket

client = socket.socket()
client.connect(('127.0.0.1',10086))
client.send(b'hello')
client.send(b'world')
from_server_data = client.recv(1024)
print(from_server_data)
client.close()
运行结果:
b'helloworld'

 

上一篇:问题记录


下一篇:Python网络编程