Любая причина, почему socket.send () зависает? - PullRequest
1 голос
/ 09 августа 2009

Я пишу мини-FTP-сервер на Python, который предоставляет базовую базу данных, как если бы это был FTP. Поток примерно такой:

sock.send("150 Here's the file you wanted\r\n")
proc = Popen2(...)
for parts in data:
    data_sock.send(parts)
proc.kill()
sock.send("226 There's the file you wanted\r\n")
data_sock.shutdown(0)
data_sock.close()

data_sock - это работающий и работающий сокет PASV, подтвержденный Wireshark. На самом деле, после отправки 163,328-го байта через data_sock строка data_sock.send () просто зависает. Я подозреваю, что буфер отправки заполнен, но для меня загадка, почему клиенты FTP не будут читать данные из сокета PASV.

Я включил строку Popen2 (...), потому что мне удалось воспроизвести http://bugs.python.org/issue3006 на OS X - сокеты не закрываются, пока не завершится процесс Popen. Не уверен, что это как-то связано.

Ответы [ 3 ]

1 голос
/ 09 августа 2009

Трудно сказать из этого фрагмента кода, не зная клиента, но возможно ли, что отправка 150 (указывает на новый канал данных), а не 125 (указывает на использование существующего канала данных) сбивает с толку клиента, и это просто делает не начать читать данные?

Вы рассматривали pyftpdlib как альтернативу для прокрутки своего собственного сервера?

0 голосов
/ 09 августа 2009

Одна из причин, по которой клиент может прекратить чтение данных, заключается в том, что кто-то отключил клиент (или отключил его кабель Ethernet) во время передачи. В этом случае TCP будет (безуспешно) повторно посылать пакеты в течение нескольких минут, не получая ответа, пока не сдастся. Есть и другие возможные причины.

Поскольку с вышеуказанными возможностями вам придется иметь дело, если вы хотите иметь надежный сервер, реальный вопрос не обязательно в том, почему это происходит, а в том, что вы должны делать, когда это происходит. Вот некоторые возможные вещи:

  1. Убедитесь, что у клиентов нет ошибок, из-за которых они перестают читать, даже если данные доступны
  2. Убедитесь, что сервер не блокируется, даже если вызов send () определенного соединения блокируется (вы можете сделать это через select () / poll () и неблокирующие сокеты, или, возможно, через многопоточность ... I рекомендую первое, если это возможно)
  3. Добавьте некоторую логику тайм-аута для select (), чтобы, если прошло более (N) секунд, когда сокет имеет данные, готовые для отправки, но на самом деле не отправляет их, сервер сдается и закрывает сокет. (TCP делает это сам, но время ожидания TCP может быть слишком длинным на ваш вкус)
0 голосов
/ 09 августа 2009

Я столкнулся с подобными проблемами на стороне клиента при загрузке, которые, кажется, связаны с удушением модема / маршрутизатора - единственное рабочее решение, которое у меня есть на данный момент, - это ограничение скорости передачи (отправка 128 байтов, сон ~ 50 мс повторить).

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