Как передать данные на удалённый компьютер?
Появилась потребность отправлять результат обработки данных на удалённый компьютер (сервер). Чтобы не делать этого вручную, решил добавить функцию передачи данных (либо файла) в скрипт.
Я плохо понимаю сетевые ньюансы подключения и передачи данных и файлов, но немного погуглив, решил, что мне подойдёт подключение 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] Удаленный хост принудительно разорвал существующее подключение
Подскажите, пожалуйста, что именно я делаю не так? Почему не удаётся подключится к удалённому компьютеру? На данный момент трудность заключается в подключении, логику передачи данных я смогу сделать, но буду благодарен если поделитесь и ею.