Как передать данные на удалённый компьютер?

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

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

На данный момент я имею следующий код:

socket(server)

import socket
import struct
import logging
import sys


logging.basicConfig(level=logging.INFO,
                    format="""[%(asctime)s] %(filename)s[LINE:%(lineno)d] %(levelname)-8s %(message)s""", 
                    encoding="utf-8",
                    handlers=[
                        logging.StreamHandler(stream=sys.stdout)
                    ])

def receive_file_size(sck: socket.socket):
    """ Func set byte size, file size. """
    fmt = "<Q"
    # Generate byte sequence
    expected_bytes = struct.calcsize(fmt)
    received_bytes = 0
    stream = bytes()
    while received_bytes < expected_bytes:
        chunk = sck.recv(expected_bytes - received_bytes)
        stream += chunk
        received_bytes += len(chunk)
    filesize = struct.unpack(fmt, stream)[0]
    return filesize

def receive_file(sck: socket.socket, filename):
    """Read from the socket the number
       bytes to be received from the file."""
    filesize = receive_file_size(sck)
    # New file
    with open(filename, "wb") as f:
        received_bytes = 0
        # Get data from file(f) 1024 bytes, overall volume.
        while received_bytes < filesize:
            chunk = sck.recv(1024)
            if chunk:
                f.write(chunk)
                received_bytes += len(chunk)
with socket.create_server(("localhost", 6190)) as server:
    logging.info("Waiting for client...")
    conn, address = server.accept()
    logging.info(f"{address[0]}:{address[1]} connected.")
    logging.info("Getting file....")
    receive_file(conn, "C:/Users/user/Desktop/loaded_data.xlsx")
    logging.info("File received.")
logging.info("Connection closed.")

socket(client)

import os
import socket
import struct
import logging

def send_file(sck: socket.socket, filename):
    filesize = os.path.getsize(filename)
    sck.sendall(struct.pack("<Q", filesize))
    with open(filename, "rb") as f:
        while read_bytes := f.read(1024):
            sck.sendall(read_bytes)

with socket.create_connection(("server's ip", 6190)) as conn:
    logging.info("Подключение к серверу.")
    logging.info("Передача файла...")
    send_file(conn, "F:/Workflow/parsers/company_1/file_to_load.xlsx")
    logging.info("Отправлено.")
logging.info("Соединение закрыто.")

Вывод socket`а:

TimeoutError: [WinError 10060] Попытка установить соединение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или было разорвано уже установленное соединение из-за неверного отклика 
уже подключенного компьютера

Сначала я запускаю скрипт на сервере, потом у клиента. У сервера проверял прослушку порта, он работал, правда ограничение брандмауэра я просмотреть не смогу.

ssh

import paramiko
import time
import socket
from pprint import pprint


def send_show_command(ip, username, password, enable, command, max_bytes=60000, short_pause=1, long_pause=5):
    cl = paramiko.SSHClient()
    cl.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    cl.connect(
        hostname=ip,
        username=username,
        password=password,
        look_for_keys=False,
        allow_agent=False,
    )
    # In future will be load file logic here
    with cl.invoke_shell() as ssh:
        ssh.send("enable\n")
        ssh.send(f"{enable}\n")
        time.sleep(short_pause)
        ssh.send("terminal length 0\n")
        time.sleep(short_pause)
        ssh.recv(max_bytes)

        result = {}
        for command in commands:
            ssh.send(f"{command}\n")
            ssh.settimeout(5)

            output = ""
            while True:
                try:
                    part = ssh.recv(max_bytes).decode("utf-8")
                    output += part
                    time.sleep(0.5)
                except socket.timeout:
                    break
            result[command] = output

        return result


if __name__ == "__main__":
    devices = ["server's ip"]
    commands = ["sh clock", "sh arp"]
    result = send_show_command("server's ip", "login", "password", "cisco", commands)
    pprint(result, width=120)

Вывод ssh:

# Если указывать порт в connect
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner[WinError 10054] Удаленный хост принудительно разорвал существующее подключение


# Если указывать look_for_keys=False
    paramiko.ssh_exception.SSHException: Error reading SSH protocol banner[WinError 10054] Удаленный хост принудительно разорвал существующее подключение

Подскажите, пожалуйста, что именно я делаю не так? Почему не удаётся подключится к удалённому компьютеру? На данный момент трудность заключается в подключении, логику передачи данных я смогу сделать, но буду благодарен если поделитесь и ею.


Ответы (0 шт):