首页 > 编程语言 > 详细

python-粘包,切换目录

时间:2019-09-05 21:47:51      阅读:90      评论:0      收藏:0      [点我收藏+]

一.粘包

  只有tcp协议才会发生粘包,udp不会  在tcp协议中:

    有一个合包机制(nagle 算法),将多次连续发送且间隔小的数据,将其打包一块数据传送
还有一个机制就是拆包机制,因为受到网卡的MTU限制的数据,进行拆分,拆分成多个小的数据,进行传输
当传输到目标主机的操作系统层时,会重新将多个小的数据合并成原本的数据
为什么udp不会发生粘包?
udp不会发生粘包,udp协议本层对一次收发数据大小的限制是:
        65535 - IP包头(20) - udp包头(8) = 65507

   站在数据链路层,应为网卡的MTU一般限制在了1500,所以对于数据链路层来说,一次发数据的大小被限制在
        1500 - ip包头(20) - udp包头(8) = 1472

    得到的结论:
        如果sendto(num)
        num > 65507 报错
        1472 < num < 65507 会在数据链路层拆包,而udp本身就是不可靠的协议,
        一旦拆包之后,造成的多个小数据包在网络传输中,如果丢任何一个,那么此次数据传输失败
        num < 1472  是比较理想的状态

二.执行命令(subprocess)

cmd = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)

# cmd : 代表系统命令
# shell = True : 代表这个命令是 系统命令;告诉操作系统,把cmd当成系统命令执行
# stdout  : 是执行完系统命令之后,用于保存结果的一个管道
# stderr : 是执行完系统命令之后,用于保存错误的一个管道

服务器端:

import socket
import subprocess

sk = socket.socket()
sk.bind((‘127.0.0.1‘,8080))
sk.listen()

conn,addr = sk.accept()

while 1:
    msg_r = conn.recv(1024).decode(‘utf-8‘)
    result = subprocess.Popen(msg_r,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)

    # print(result.stdout.read().decode(‘gbk‘))
    # print(result.stderr.read())
    stdout = result.stdout.read()
    stderr = result.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))

    msg_r = sk.recv(10240).decode(gbk)
    print(msg_r)

sk.close()

三.大文件传输

服务器端:

import socket
import json
import struct

sk = socket.socket()

sk.bind((127.0.0.1,8080))
sk.listen()

conn,addr = sk.accept()

# str_dic = conn.recv(100).decode(‘utf-8‘)
# dic = json.loads(str_dic)
# print(dic)
b_len_dic = conn.recv(4)
len_dic = struct.unpack(i,b_len_dic)[0]
str_dic = conn.recv(len_dic).decode(utf-8)
dic = json.loads(str_dic)
print(dic)

# conn.send(b‘OK‘)

if dic[opt] == upload:
    filename = 1 + dic[filename]
    with open(filename,mode=ab) as f:
        while dic[filesize]:
            content = conn.recv(1024)
            f.write(content)
            dic[filesize] -= len(content)

conn.close()
sk.close()

客户端:

import socket
import os
import json
import struct  

sk = socket.socket()

sk.connect_ex((127.0.0.1,8080))

meau = {1:upload,2:download}
num = input(请输入选项功能>>>)
dic = {opt:meau.get(num),filename:None,filesize:None}

file_path = input(请输入一个绝对路径>>>)
filename = os.path.basename(file_path)
dic[filename] = filename

filesize = os.path.getsize(file_path)
dic[filesize] = filesize

str_dic = json.dumps(dic)

len_dic = len(str_dic)
b_len_dic = struct.pack(i,len_dic)  # 将字典的长度打包成一个4bytes的数据
sk.send(b_len_dic+str_dic.encode(utf-8))

# sk.recv(1024)   # 为什么要在这里加上一个recv?主要是防止上一个send程序执行过快,导致下面send程序与其发生粘包,从而发生数据混乱现象



with open(file_path,mode=rb) as f:
    while filesize:
        content = f.read(1024)
        sk.send(content)
        filesize -= len(content)

sk.close()

四.切换目录

服务器端:

import socket
import os

sk = socket.socket()
sk.bind((127.0.0.1, 8080))
sk.listen()

conn, addr = sk.accept()


def send_data(conn, path):
    lis_dir = os.listdir(path)
    str_dir = __.join(lis_dir)
    conn.send(str_dir.encode(utf-8))


abs_path = conn.recv(1024).decode(utf-8)
current_dir = abs_path
send_data(conn, current_dir)

while 1:
    cmd = conn.recv(1024).decode(utf-8)

    if cmd == ..:
        current_dir = /.join(current_dir.split(\\)[:-1])
        print(current_dir)
        send_data(conn,current_dir)
    else:
        filename = cmd.split( )[1]
        print(filename)
        current_dir = current_dir + // + filename
        print(current_dir)
        if os.path.isdir(current_dir):
            send_data(conn,current_dir)
        else:
            conn.send(不是一个文件夹名.encode(utf-8))

conn.close()
sk.close()

客户端:

import socket
import os

sk = socket.socket()

sk.connect_ex((127.0.0.1, 8080))

abs_path = input(请输入您的根目录>>>)
sk.send(abs_path.encode(utf-8))
current_dir = sk.recv(1024).decode(utf-8)
print(current_dir.split(__))

while 1:
    cmd = input(>>>)

    if cmd == ..:
        sk.send(cmd.encode(utf-8))
        current_dir = sk.recv(1024).decode(utf-8)
        print(current_dir.split(__))
    elif cmd == cd:
        filename = input(请输入一个文件夹名>>>)
        sk.send((cmd+ +filename).encode(utf-8))
        current_dir = sk.recv(1024).decode(utf-8)
        print(current_dir.split(__))

sk.close()

 

python-粘包,切换目录

原文:https://www.cnblogs.com/jiujiang/p/11469787.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!