首页 > 解决方案 > 如何通过套接字以“块”形式发送文件?

问题描述

我正在尝试通过分块发送文件内容(有点像种子)来通过套接字发送一个大文件(.avi)。问题是脚本不发送文件。我在这里没有想法。

脚本的任何帮助或 twerking 将不胜感激。

服务器:

import socket

HOST = ""
PORT = 8050
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(1)
conn, addr = sock.accept() 
print("Connected by ", str(addr))

while 1:
    data = conn.recv(1024)

    if data.decode("utf-8") == 'GET':
        with open(downFile,'rb') as output:
            l = output.read(1024)
            while (l):
                conn.send(l)
                l = output.read(1024)
            output.close()

conn.close()

客户:

import socket

HOST = "localhost"
PORT = 8050
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST,PORT))

while 1:

    message = input()
    sock.send(bytes(message,'UTF-8'))

    conn.send(str.encode('GET'))
    with open(downFile, 'wb+') as output:
        while True:
            rec = str(sock.recv(1024), "utf-8")
            if not rec:
                break
            output.write(rec)
        output.close()
    print('Success!')
sock.close()

标签: pythonpython-3.xsockets

解决方案


这是一个工作的客户端和服务器,应该演示通过套接字传输文件。我对您的代码应该做什么做了一些假设,例如,我假设客户端发送到服务器的初始消息应该是要下载的文件的名称。

该代码还包括一些附加功能,供服务器向客户端返回错误消息。在运行代码之前,请确保 指定的目录DOWNLOAD_DIR存在。

客户:

import socket
import sys
import os

HOST = "localhost"
PORT = 8050
BUF_SIZE = 4096
DOWNLOAD_DIR = "downloads"

def download_file(s, down_file):
    s.send(str.encode("GET\n" + down_file))
    rec = s.recv(BUF_SIZE)
    if not rec:
        return "server closed connection"

    if rec[:2].decode("utf-8") != 'OK':
        return "server error: " + rec.decode("utf-8")

    rec = rec[:2]
    if DOWNLOAD_DIR:
        down_file = os.path.join(DOWNLOAD_DIR, down_file)
    with open(down_file, 'wb') as output:
        if rec:
            output.write(rec)
        while True:
            rec = s.recv(BUF_SIZE)
            if not rec:
                break
            output.write(rec)

    print('Success!')
    return None

if DOWNLOAD_DIR and not os.path.isdir(DOWNLOAD_DIR):
    print('no such directory "%s"' % (DOWNLOAD_DIR,), file=sys.stderr)
    sys.exit(1)

while 1:
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        sock.connect((HOST, PORT))
    except Exception as e:
        print("cannot connect to server:", e, file=sys.stderr)
        break

    file_name = input("\nFile to get: ")
    if not file_name:
        sock.close()
        break

    err = download_file(sock, file_name)
    if err:
        print(err, file=sys.stderr)
    sock.close()

服务器:

import socket
import sys
import os

HOST = ""
PORT = 8050
BUF_SIZE = 4096

def recv_dl_file(conn):
    data = conn.recv(1024)
    if not data:
        print("Client finished")
        return None, None

    # Get command and filename
    try:
        cmd, down_file = data.decode("utf-8").split("\n")
    except:
        return None, "cannot parse client request"
    if cmd != 'GET':
        return None, "unknown command: " + cmd

    print(cmd, down_file)
    if not os.path.isfile(down_file):
        return None, 'no such file "%s"'%(down_file,)

    return down_file, None


def send_file(conn):
    down_file, err = recv_dl_file(conn)
    if err:
        print(err, file=sys.stderr)
        conn.send(bytes(err, 'utf-8'))
        return True

    if not down_file:
        return False # client all done

    # Tell client it is OK to receive file
    sent = conn.send(bytes('OK', 'utf-8'))

    total_sent = 0
    with open(down_file,'rb') as output:
        while True:
            data = output.read(BUF_SIZE)
            if not data:
                break
            conn.sendall(data)
            total_sent += len(data)

    print("finished sending", total_sent, "bytes")
    return True


sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(1)
keep_going = 1
while keep_going:
    conn, addr = sock.accept()
    print("Connected by", str(addr))
    keep_going = send_file(conn)
    conn.close() # close clien connection
    print()

sock.close() # close listener

推荐阅读