Недавно я написал код (клиент и сервер) для отправки изображения - клиент просто загружает изображение на сервер, просто используя модуль socket
: Отправка изображения через сокеты (ТОЛЬКО) в Python, изображение не может быть открыто.
Тем не менее, часть отправки изображения теперь является тем, чем я занимаюсь. Это исходное изображение, которое я использую:
В моем коде сервера (который принимает изображения) у меня есть следующие строки:
myfile = open(basename % imgcounter, 'wb')
myfile.write(data)
data = sock.recv(40960000)
if not data:
myfile.close()
break
myfile.write(data)
myfile.close()
sock.sendall("GOT IMAGE")
sock.shutdown()
Но я не думаю, что это лучший способ сделать это. Я думаю, что вместо этого я должен использовать сервер таким образом, чтобы он получал данные в кусках:
#!/usr/bin/env python
import random
import socket, select
from time import gmtime, strftime
from random import randint
imgcounter = 1
basename = "image%s.png"
HOST = '127.0.0.1'
PORT = 2905
connected_clients_sockets = []
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((HOST, PORT))
server_socket.listen(10)
connected_clients_sockets.append(server_socket)
while True:
read_sockets, write_sockets, error_sockets = select.select(connected_clients_sockets, [], [])
for sock in read_sockets:
if sock == server_socket:
sockfd, client_address = server_socket.accept()
connected_clients_sockets.append(sockfd)
else:
try:
data = sock.recv(4096)
txt = str(data)
if data:
if data.startswith('SIZE'):
tmp = txt.split()
size = int(tmp[1])
print 'got size %s' % size
sock.sendall("GOT SIZE")
elif data.startswith('BYE'):
sock.shutdown()
else :
myfile = open(basename % imgcounter, 'wb')
myfile.write(data)
amount_received = 0
while amount_received < size:
data = sock.recv(4096)
amount_received += len(data)
print amount_received
if not data:
break
myfile.write(data)
myfile.close()
sock.sendall("GOT IMAGE")
sock.shutdown()
except:
sock.close()
connected_clients_sockets.remove(sock)
continue
imgcounter += 1
server_socket.close()
Но когда я это делаю, сервер печатает:
got size 54674
4096
8192
12288
16384
20480
24576
28672
32768
36864
40960
45056
49152
50578
А потом, кажется, висит, и клиент тоже висит. Однако на стороне сервера я вижу только часть изображения, которую клиент хотел отправить:
Кажется, что некоторые байты отсутствуют. Каков правильный способ отправки огромного количества данных (изображений, другого типа файлов) с использованием ТОЛЬКО сокетов?