链接循环+模拟远程执行命令+实现大文件上传

循环链接

###服务端

import socket

server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)

###要实现循环链接,也就是一个链接段了之后,我们又可以继续链接其他的
##服务端要提供持续不断的服务

while True:
    conn, addr = server.accept()
    while True:
        try:
            data = conn.recv(1024)  # b''
            if len(data) == 0:break  # 针对mac linux系统而言
            print(data)
            conn.send(data.upper())
        except ConnectionResetError:
            break
    conn.close()

server.close()
###这个代码变成黄色,表示代码永远执行不到这里,
###上面是一个死循环,这个pycharm 自动检测到后的提示

##客户端

import socket

client = socket.socket()
client.connect(('127.0.0.1',8080))

while True:
    msg = input('please input your msg>>>:').encode('utf-8')
    if len(msg) == 0:continue
    client.send(msg)
    data = client.recv(1024)
    print(data)


模拟远程执行命令

##现在我们要写一个CS框架的程序,在之前的基础上,
##实现模拟远程输入一个命令,服务器执行,并将执行的结果发送给本地主机,并且打印出来
##但是因为执行的结果可能很长,所以会有粘包问题的产生 所以我们要重点解决粘包的问题


'''
解决思路:
1,客户端将命令发送到服务端, 服务端接收命令,这个接收命令就直接接收1024字节就可以  因为命令的长度一般不可能超过这个长度
2,服务端调用subprocess 模块,执行命令,然后得到执行的结果
3,因为执行得到的结果长度不确定,可能很大,也可能很小,所以我们需要将提前将结果的长度发过去
4,我们直接len() 得到需要传过去的数据的长度,然后利用 struct 模块,将这个长度数据转化成
##固定长度的数据 发送过去
5,客户端接收到这个数据长度之后,如果数据量很大,就循环接收拼接这个数据,然后将数据打印出来

'''

###服务端

import socket
import subprocess
import struct
import json

server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)


while True:
    conn, addr = server.accept()
    while True:
        try:
            cmd = conn.recv(1024).decode('utf-8')
            if len(cmd) == 0:break
            obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
            stdout = obj.stdout.read()
            stderr = obj.stderr.read()
            print(len(stdout+stderr))
            send_dic = {"name":'jason','password':'123','total_size':len(stdout+stderr)}
            send_bytes = json.dumps(send_dic).encode('utf-8')
            # 先制作字典的报头
            header = struct.pack('i',len(send_bytes))
            # 发送报头
            conn.send(header)
            # 再发字典
            conn.send(send_bytes)
            # 最后再发真实数据
            conn.send(stdout+stderr)
        except ConnectionResetError as e:
            print(e)
            break
    conn.close()
server.close()

##客户端
import socket
import struct
import json

client = socket.socket()
client.connect(('127.0.0.1',8080))


while True:
    cmd = input('please input your cmd>>>:').encode('utf-8')
    if len(cmd) == 0:continue
    client.send(cmd)
    # 先接收报头
    header = client.recv(4)
    # 解析获取字典的长度
    dic_len = struct.unpack('i',header)[0]
    dic_bytes = client.recv(dic_len)
    real_dic = json.loads(dic_bytes.decode('utf-8'))
    print(real_dic)
    # 循环接收真实数据
    data = b''
    recv_size = 0
    while recv_size < real_dic['total_size']:
        info = client.recv(1024)
        data += info
        recv_size += len(info)
    print(data.decode('gbk'))

实现大文件上传

###服务端

import socket
import struct
import json
from socket import SOL_SOCKET,SO_REUSEADDR


server = socket.socket()
server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
server.bind(('127.0.0.1',8080))
server.listen(5)

conn,addr = server.accept()
# 先收4个长度报头
header = conn.recv(4)
# 获取字典长度
dic_len = struct.unpack('i',header)[0]
# 接收字典
dic_bytes = conn.recv(dic_len)
real_dic = json.loads(dic_bytes.decode('utf-8'))
# 获取文件相关信息
file_name = real_dic.get('file_name')
total_size = real_dic.get("file_size")
with open(file_name,'wb') as f:
    # 循环接收文件
    recv_size = 0
    while recv_size < total_size:
        data = conn.recv(1024)
        f.write(data)
        recv_size += len(data)
    print('文件上传成功')
    
##客户端

import socket
import struct
import json
import os

client = socket.socket()
client.connect(('127.0.0.1',8080))


file_path = r'D:python周末四期day111.时间模块.mp4'
file_size = os.path.getsize(file_path)  # 获取文件大小
send_dic = {"file_name":'FBI warning','file_info':"注意身体",'file_size':file_size}
send_bytes = json.dumps(send_dic).encode('utf-8')
# 制作报头
head = struct.pack('i',len(send_bytes))
# 发送报头
client.send(head)
# 发字典
client.send(send_bytes)
# 发文件
with open(file_path,'rb') as f:
    for line in f:
        client.send(line)




原文地址:https://www.cnblogs.com/1832921tongjieducn/p/10969794.html