Как отправить файлы в «чанках» сокетом? - PullRequest
0 голосов
/ 02 октября 2018

Я пытаюсь отправить большой файл (.avi) через сокет, отправляя содержимое файла кусками (немного похоже на торренты).Проблема в том, что скрипт не отправляет файл.У меня нет идей здесь.

Буду очень признателен за любую помощь или исправление сценария.

Сервер:

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

1 Ответ

0 голосов
/ 02 октября 2018

Вот работающий клиент и сервер, которые должны продемонстрировать передачу файла через сокет.Я сделал некоторые предположения о том, что должен делать ваш код, например, я предположил, что исходное сообщение, отправляемое клиентом на сервер, должно быть именем файла для загрузки.

Код также включаетнекоторые дополнительные функции для сервера, чтобы возвращать сообщение об ошибке клиенту.Перед запуском кода убедитесь, что каталог, указанный 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...