Отправка файла через сокет - PullRequest
2 голосов
/ 26 мая 2010

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

Я работаю с необработанными пакетами, используя send и recv, но решил, что это более чистое решение ...

Клиент:

  1. подключается к серверу, создающему сокетное соединение
  2. создает файл в сокете и отправляет данные
  3. ожидает файл с сервера

Сервер:

  1. ожидает файл от клиента

Полное взаимодействие:

  1. клиент отправляет данные на сервер
  2. сервер отправляет данные клиенту

Редактировать

Код, который я на самом деле смотрю, был опубликован в этом вопросе, но я думаю, что материал из Eventlet напугал людей ... https://stackoverflow.com/questions/2909358/eventlet-client-server

Под ней просто используются сокеты Python, так что я решил упростить вопрос и задать вопрос только о ядре сокета ...

Ответы [ 3 ]

3 голосов
/ 27 мая 2010

Похоже, у вас есть клиент, отправляющий файл и ожидающий ответа сервера, но если вы не дадите серверу указание, что он полностью прочитал файл, recv () на стороне сервера будет зависать для получения дополнительных данных. Вы можете вызвать shutdown (SHUT_WR) на стороне клиента, как только клиент завершит отправку. Это информирует сервер о том, что после прочтения всех отправленных данных его больше нет.

Очень простой пример (отправка одного блоба данных на сервер и получение одного блоба данных в ответ):

Сервер

>>> from socket import *
>>> s=socket()
>>> s.bind(('',8000))
>>> s.listen(1)
>>> c,a = s.accept()  # will hang here until a client connects
>>> recvd=''
>>> while True:
...  data = c.recv(1024)
...  if not data: break # recv() will return '' only if the client calls shutdown(SHUT_WR) or close()
...  recvd += data
...
>>> recvd
'a message'
>>> c.sendall('a response')
>>> c.close()  # done with client, could loop back to accept here
>>> s.close()  # done with server

клиент

>>> from socket import *
>>> s=socket()
>>> s.connect(('localhost',8000))
>>> s.sendall('a message')
>>> s.shutdown(SHUT_WR)  # tells server you're done sending, so recv won't wait for more
>>> recvd=''
>>> while True:
...  data = s.recv(1024)
...  if not data: break
...  recvd += data
...
>>> recvd
'a response'
>>> s.close()
1 голос
/ 26 мая 2010

Я не уверен, что вопрос ясен, вы спрашиваете:

  1. Как отправить данные всего файла через сокет?
  2. Как заставить писателя блокировать после записи некоторых данных?
  3. Что-то еще вообще ??

Если вопрос # 1, вам нужно открыть файл и разобрать его в поток байтов, а затем передать всю коллекцию байтов за один вызов write.

Если вопрос №2, то есть вы хотите, чтобы писатель подождал, пока читатель полностью прочитает байты (и обработал их ??), прежде чем двигаться дальше, тогда вам нужно, чтобы читатель и писатель согласовали. Вы можете сделать это, вызвав писателя read (чтение - блокирующий вызов) после записи. Затем, после того как читатель закончит чтение (и обработает байты), пусть он напишет что-нибудь автору, чтобы разбудить его.

Если вопрос №3, возможно, вы можете предоставить более подробную информацию.

0 голосов
/ 27 мая 2010

Я не совсем понимаю, о чем вы спрашиваете, но, возможно, вы ищете select?

http://docs.python.org/library/select.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...