TCP отправка нескольких файлов
path = os.path.join("C:\\Users", os.environ["username"],"cloud")
HOST = '127.0.0.1' # Get local machine name
PORT = 12345 # Reserve a port for your service.
ADDR = (HOST, PORT)
bufsize = 1024
tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)
data = ''
f = open(i, 'rb')
print("start while")
while data != b'':
print(i)
data = f.read(bufsize)
tcpCliSock.send(data)
Примерно так я отправляю файл на ТСП сервер
while True:
body = tcpCliSock.recv(bufsize).decode()
print(body)
if not body:
print("end")
break
bb = bb+body
В таком вот цикле я получаю передаваемый файл в переменную bb. Возник вопрос, если я хочу передать несколько файлов, например file = ['file.png', 'file.txt'] я попытался сделать цикл в котором отправлял бы файлы, условно так
fir i in file:
file=open(i,"")
data = file.read()
tcpCliSock.send(data)
Но после передачи первого файла ТСП сервер закрывает соединение
отрабатывает условие if not body:
Что я делаю не правильно?
Ответы (2 шт):
Автор решения: gil9red
→ Ссылка
такая же проблема, первый файл передается а второй нет
Рабочий код, попробуйте:
client.py
import socket
from common import send_msg, recv_msg
HOST, PORT = "localhost", 9090
for file_name in ['img.png', 'img2.png']:
with socket.socket() as sock:
sock.connect((HOST, PORT))
with open(file_name, 'rb') as f:
data = f.read()
print('Sending ({}): {}'.format(len(data), data))
print()
send_msg(sock, data)
print('Receiving')
response_data = recv_msg(sock)
print('Response ({}): {}'.format(len(response_data), response_data))
print('Close\n')
server.py
import socket
from common import send_msg, recv_msg
PORT = 9090
with socket.socket() as sock:
sock.bind(('', PORT))
sock.listen()
print('Server: {}'.format(sock.getsockname()))
while True:
conn, addr = sock.accept()
print('Connected:', addr)
data = recv_msg(conn)
print('Receiving ({}): {}'.format(len(data), data))
text = 'Ok! Message size: {}'.format(len(data))
print('Sending: {}'.format(text))
rs = bytes(text, 'utf-8')
send_msg(conn, rs)
print('Close\n')
common.py:
import struct
from typing import Optional
def send_msg(sock, msg):
# Prefix each message with a 8-byte length (network byte order)
msg = struct.pack('>Q', len(msg)) + msg
sock.sendall(msg)
def recv_msg(sock) -> Optional[bytes]:
# 8-byte
payload_size = struct.calcsize(">Q")
# Read message length and unpack it into an integer
raw_msg_len = recv_all(sock, payload_size)
if not raw_msg_len:
return None
msg_len = struct.unpack('>Q', raw_msg_len)[0]
# Read the message data
return recv_all(sock, msg_len)
def recv_all(sock, n) -> Optional[bytes]:
# Helper function to recv n bytes or return None if EOF is hit
data = bytearray()
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data += packet
return bytes(data)
Автор решения: Krutoy 4el
→ Ссылка
Опыта с сокетами у меня мало, но вот маленький вспомогательный класс, который может отправлять и принимать файлы/любые двоичные данные.
import socket
class Port:
def __init__(self):
self._sock=socket.socket()
def listen(self, address: str, port: int):
self._sock.bind((address, port))
self._sock.listen()
self._sock=self._sock.accept()[0]
def connect(self, address: str, port: int):
self._sock.connect((address, port))
def send(self, data: bytes):
data_l=str(len(data)).encode()
self._sock.send(len(data_l).to_bytes(1, "big"))
self._sock.send(data_l)
self._sock.send(data)
def receive(self):
data_l=self._sock.recv(1)[0]
data_l=int(self._sock.recv(data_l).decode())
return self._sock.recv(data_l)