网络编程(套接字)之粘包、报头等相关内容-32

1.socket接入多个客户端

# server.py

from socket import *

server = socket(AF_INET, SOCK_STREAM)
# print(server)
server.bind(('127.0.0.1', 8080))
server.listen(5)
while True:
   conn, client_addr = server.accept()
   print(conn)
   print(client_addr)

   while True:
       try:
           data = conn.recv(1024)
           conn.send(data.upper())
       except Exception:
           break
   conn.close()

server.close()


# client.py

from socket import *

client = socket(AF_INET, SOCK_STREAM)
# print(client)
client.connect(('127.0.0.1', 8080))

while True:
   cmd = input(">>: ").strip()
   if len(cmd) == 0:
       continue
   client.send(cmd.encode('utf-8'))
   print('=======>')
   data = client.recv(1024)
   print('111111')
   print(data.decode('utf-8'))
client.close()

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

# server.py

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()


# client.py

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()

3.定制复杂的报头

# server.py

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()


# client.py

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()
# server.py

import subprocess
import os
import struct
import json
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":
               # 一、制作报头
               header_dic={
                   "total_size":os.path.getsize(file_path),
                   "filename":os.path.basename(file_path),
                   "md5":"1231231231232132131232311"
              }
               header_json=json.dumps(header_dic)
               header_json_bytes=header_json.encode('utf-8')


               # 二、发送数据
               # 1、先发送报头的长度
               header_size=len(header_json_bytes)
               conn.send(struct.pack('i',header_size))
               # 2、再发送报头
               conn.send(header_json_bytes)
               # 3、最后发送真实的数据
               with open(r'%s' %file_path,mode='rb') as f:
                   for line in f:
                       conn.send(line)
       except Exception:
           break
   conn.close()

server.close()

# client.py

import struct
import json
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'))

   # 1、先接收报头的长度
   res=client.recv(4)
   header_size=struct.unpack('i',res)[0]
   # 2、再接收报头
   header_json_bytes=client.recv(header_size)
   header_json=header_json_bytes.decode('utf-8')
   header_dic=json.loads(header_json)
   print(header_dic)
   # 3、最后接收真实的数据
   total_size=header_dic['total_size']
   filename=header_dic['filename']
   recv_size = 0
   with open(r"D:\python全栈15期\day32\代码\03 定制复杂的报头\版本2\download\%s" %filename, mode='wb') as f:
       while recv_size < total_size:
           data = client.recv(1024)
           f.write(data)
           recv_size += len(data)


client.close()

 

posted @ 2020-08-17 09:20  投降输一半!  阅读(216)  评论(0编辑  收藏  举报