远程执行命令解决程序粘包问题

远程执行命令解决程序粘包问题

客服端

import struct
from socket import *

client = socket(AF_INET, SOCK_STREAM)

# print(client)

client.connect(('127.0.0.1', 8082))

while True:
  cmd = input(">>: ").strip()
  if len(cmd) == 0:
      continue
  client.send(cmd.encode('utf-8'))

  # 先收数据的长度
  n = 0
  header = b''
  while n < 4:
      data = client.recv(1)
      header += data
      n += len(data)
   
  total_size = struct.unpack('i', header)[0]
   
  # 收真正的数据
  recv_size = 0
  res = b''
  while recv_size < total_size:
      data = client.recv(1024)
      res += data
      recv_size += len(data)
   
  print(res.decode('gbk'))

client.close()

服务端

import subprocess
import struct
from socket import *

server = socket(AF_INET, SOCK_STREAM)

# print(server)

server.bind(('127.0.0.1', 8082))
server.listen(5)
while True:
  conn, client_addr = server.accept()
  print(conn)
  print(client_addr)

  while True:
      try:
          cmd = conn.recv(1024)
          obj = subprocess.Popen(cmd.decode('utf-8'),
                                  shell=True,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  )
   
          stdout = obj.stdout.read()
          stderr = obj.stdout.read()
          total_size = len(stdout) + len(stderr)
   
          # 先发送数据的长度
          conn.send(struct.pack('i',total_size))
          # 发送真正的数据
          conn.send(stdout)
          conn.send(stderr)
      except Exception:
          break
  conn.close()

server.close()
定制复杂的报头
客服端

import struct
from socket import *

client = socket(AF_INET, SOCK_STREAM)

# print(client)

client.connect(('127.0.0.1', 8082))

while True:
  cmd = input(">>: ").strip() # get 文件路径
  if len(cmd) == 0:
      continue
  client.send(cmd.encode('utf-8'))

  # 先收数据的长度
  n = 0
  header = b''
  while n < 8:
      data = client.recv(1)
      header += data
      n += len(data)
   
  total_size = struct.unpack('q', header)[0]
  print(total_size)
  # 收真正的数据
  recv_size = 0
  with open('aaa.jpg', mode='wb') as f:
      while recv_size < total_size:
          data = client.recv(1024)
          f.write(data)
          recv_size += len(data)


client.close()

服务端

import subprocess
import os
import struct
from socket import *

server = socket(AF_INET, SOCK_STREAM)

# print(server)

server.bind(('127.0.0.1', 8082))
server.listen(5)
while True:
  conn, client_addr = server.accept()
  print(conn)
  print(client_addr)

  while True:
      try:
          msg = conn.recv(1024).decode('utf-8')
          cmd,file_path=msg.split()
          if cmd == "get":
              # 先发送报头
              total_size=os.path.getsize(file_path)
              conn.send(struct.pack('q',total_size))
              # 再发送文件
              with open(r'%s' %file_path,mode='rb') as f:
                  for line in f:
                      conn.send(line)
      except Exception:
          break
  conn.close()

server.close()
基于udp协议通信编程

TCP  VS  UDP协议

# 1、可靠性

# tcp协议是可靠协议:

#   对方必须回复一个ack确认信息,才会将自己这端的数据从内存中删除

# udp协议不可靠:

#   发送一条消息就会立即删除,不管对方是否接收到

# 2、有无链接

# tcp有链接,udp无链接

# 3、传输数据的效率

# udp更高

# 4、粘包问题

# udp协议称之为数据报协议,每次发送都是一个完整的数据报,一个发送唯一对应一个接收

# 所以udp协议没有粘包问题

代码示==》服务端

from socket import *
import time

server = socket(AF_INET, SOCK_DGRAM)
server.bind(('127.0.0.1', 8080))

while True:
  data, client_addr = server.recvfrom(1024)
  time.sleep(10)
  server.sendto(data.upper(), client_addr)

客服端

from socket import *

client = socket(AF_INET, SOCK_DGRAM)

while True:
  msg = input('>>: ').strip()
  client.sendto(msg.encode("utf-8"), ('127.0.0.1', 8080))

data, server_addr = client.recvfrom(1024)
print(data.decode('utf-8'))
每天逼着自己写点东西,终有一天会为自己的变化感动的。这是一个潜移默化的过程,每天坚持编编故事,自己不知不觉就会拥有故事人物的特质的。 Explicit is better than implicit.(清楚优于含糊)
原文地址:https://www.cnblogs.com/kylin5201314/p/13523499.html