网络编程-文件传输

功能实现:

server:

import socket,os
import subprocess
import struct
import json
import os
share_dir=r"E:\Code\PyCharm\Luf\Chapter06-网络编程\09_文件上传下载\server\share"
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
while True:
    conn,client_addr=phone.accept()
    print(client_addr)
    while True:
        try:
            #1、接收命令
            res=conn.recv(8096)
            if not res: break
            #2、解析命令,提取相应命令参数
            cmds=res.decode("utf-8").split()
            filename=cmds[1]
            file_full_path=os.path.join(share_dir,filename)

            #第一步,制作固定长度的报头
            header_dic={
                'filename':filename,
                'md5':1,
                'file_size':os.path.getsize(file_full_path)
            }
            header_bytes=json.dumps(header_dic).encode("utf-8")
            header=struct.pack('i',len(header_bytes))
            #第二步,先发送报头的长度
            conn.send(header)
            #第三步,发送报头
            conn.send(header_bytes)
            #第四步,发送真实数据
            # 3、以读的方式打开文件,读取文件内容,发送给客户端
            with open(file_full_path, 'rb') as f:
                for line in f:
                    conn.send(line)
            print("send file is end")
        except ConnectionResetError:
            break
    conn.close()#连接关闭
phone.close()#套接字关闭
View Code

 client:

import socket
# client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# client.connect(('127.0.0.1',8080))
# client.send('hello'.encode('gbk'))
# client.send('world'.encode('gbk'))
# # while True:
# #     #1、发送命令
# #     cmd=input('>> ').strip()
# #     if not cmd:continue
# #     client.send(cmd.encode('gbk'))
# #     #2、拿到结果并打印
# #     data=client.recv(1024).decode('gbk')#1024是坑
# #     print(data)
# client.close()
import socket
import struct
import json
import os
download_dir=r"E:\Code\PyCharm\Luf\Chapter06-网络编程\09_文件上传下载\client\download"
client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',8080))
#通信循环
while True:
    #1、发送命令
    cmd=input('>> ').strip()#get a.txt
    if not cmd:continue#避免用户输入空字符串导致客户端卡死
    client.send(cmd.encode('utf-8'))
    #1、先拿到数据长度(包头),取得有效数据
    header=client.recv(4)
    header_size=struct.unpack('i',header)[0]
    #2、接收报头
    print(header_size)
    header_bytes=client.recv(header_size)
    #3、从报头中获取有用数据
    header_json=header_bytes.decode('utf-8')
    print(header_json)
    header_dic=json.loads(header_json)
    total_size=header_dic['file_size']

    filename=os.path.join(download_dir,header_dic['filename'])
    #打开文件写入内容
    with open(filename,'wb') as f:
        recv_size = 0
        while recv_size < total_size:
            line=client.recv(1024)
            f.write(line)
            recv_size+=len(line)
            print("总大小:%s 已下载:%s" % (total_size,recv_size))
#关闭连接
client.close()
View Code

 

 函数版本实现文件传输:

server:

import socket,os
import subprocess
import struct
import json
import os

share_dir=r"E:\Code\PyCharm\Luf\Chapter06-网络编程\09_文件上传下载\server\share"
def get(conn,cmds):
    filename = cmds[1]
    file_full_path = os.path.join(share_dir, filename)
    # 第一步,制作固定长度的报头
    header_dic = {
        'filename': filename,
        'md5': 1,
        'file_size': os.path.getsize(file_full_path)
    }
    header_bytes = json.dumps(header_dic).encode("utf-8")
    header = struct.pack('i', len(header_bytes))
    # 第二步,先发送报头的长度
    conn.send(header)
    # 第三步,发送报头
    conn.send(header_bytes)
    # 第四步,发送真实数据
    # 3、以读的方式打开文件,读取文件内容,发送给客户端
    with open(file_full_path, 'rb') as f:
        for line in f:
            conn.send(line)
    print("send file is end")
def run():
    phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    phone.bind(('127.0.0.1',8080))
    phone.listen(5)
    while True:
        conn,client_addr=phone.accept()
        print(client_addr)
        while True:
            try:
                #1、接收命令
                res=conn.recv(8096)
                if not res: break
                #2、解析命令,提取相应命令参数
                cmds=res.decode("utf-8").split()
                if cmds[0]=='get':
                    get(conn,cmds)
            except ConnectionResetError:
                break
        conn.close()#连接关闭
    phone.close()#套接字关闭
run()
View Code

client:

import socket
import struct
import json
import os
download_dir=r"E:\Code\PyCharm\Luf\Chapter06-网络编程\09_文件上传下载\client\download"
def get(client):
    # 1、先拿到数据长度(包头),取得有效数据
    header = client.recv(4)
    header_size = struct.unpack('i', header)[0]
    # 2、接收报头
    header_bytes = client.recv(header_size)
    # 3、从报头中获取有用数据
    header_json = header_bytes.decode('utf-8')
    header_dic = json.loads(header_json)
    total_size = header_dic['file_size']

    filename = os.path.join(download_dir, header_dic['filename'])
    # 打开文件写入内容
    with open(filename, 'wb') as f:
        recv_size = 0
        while recv_size < total_size:
            line = client.recv(1024)
            f.write(line)
            recv_size += len(line)
            print("总大小:%s 已下载:%s" % (total_size, recv_size))
def run():
    client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    client.connect(('127.0.0.1',8080))
    #通信循环
    while True:
        #1、发送命令
        cmd=input('>> ').strip()#get a.txt
        if not cmd:continue#避免用户输入空字符串导致客户端卡死
        client.send(cmd.encode('utf-8'))
        cmds=cmd.split()
        if cmds[0]=="get":
            get(client)
    #关闭连接
    client.close()
run()
View Code

面向对象版本:

猜你喜欢

转载自www.cnblogs.com/yaya625202/p/8960694.html