2010-05-23 1 views
5

Я пытаюсь написать простой на основе сокета клиент в Python, который будет подключаться к серверу telnet. Я могу проверить сервер по telnetting на его порт (5007) и ввести текст. Он отвечает NAK (ошибка) или AK (успех), иногда сопровождаемый другим текстом. Кажется очень простым.Соединение сокета на сервере telnet зависает при чтении

Я написал клиент для подключения и связи с сервером, но он зависает при первой попытке прочитать ответ. Соединение выполнено успешно. Запросы, такие как getsockname и getpeername, успешны. Команда send возвращает значение, равное числу символов, которые я отправляю, поэтому кажется, что они правильно отправляются. Но, в конце концов, он всегда зависает, когда я пытаюсь прочитать ответ.

Я пробовал использовать как файловые объекты, такие как readline и write (через socket.makefile), а также использовать send и recv. С файлом я попытался сделать его с помощью «rw» и чтения и записи через этот объект, а затем попробовал один объект для «r», а другой для «w» - для их разделения. Ничего из этого не сработало.

Я использовал пакетный сниффер, чтобы посмотреть, что происходит. Я не разбираюсь во всем, что вижу, но во время сеанса telnet я вижу, что мой напечатанный текст и текст сервера возвращаются. Во время моего подключения к сокету Python я вижу, что мой текст идет на сервер, но пакеты обратно, похоже, не содержат в них никакого текста.

Любые идеи о том, что я делаю неправильно или какие-либо стратегии попробовать?

Вот код, я использую (в данном случае, это с посылом и RECV):

#!/usr/bin/python 

host = "localhost" 
port = 5007 
msg = "HELLO EMC 1 1" 
msg2 = "HELLO" 

import socket 
import sys 

try: 
    skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
except socket.error, e: 
    print("Error creating socket: %s" % e) 
    sys.exit(1) 

try: 
    skt.connect((host,port)) 
except socket.gaierror, e: 
    print("Address-related error connecting to server: %s" % e) 
    sys.exit(1) 
except socket.error, e: 
    print("Error connecting to socket: %s" % e) 
    sys.exit(1) 

try: 
    print(skt.send(msg)) 
    print("SEND: %s" % msg) 
except socket.error, e: 
    print("Error sending data: %s" % e) 
    sys.exit(1) 


while 1: 
    try: 
     buf = skt.recv(1024) 
     print("RECV: %s" % buf) 
    except socket.error, e: 
     print("Error receiving data: %s" % e) 
     sys.exit(1) 
    if not len(buf): 
     break 
    sys.stdout.write(buf) 

О, в случае, если это полезно, вот пример телнет сессия сделана вручную:

ubuntu:~/mac/python$ telnet localhost 5007 
Trying 127.0.0.1... 
Connected to localhost. 
Escape character is '^]'. 
HELLO EMC 1 1 
HELLO ACK EMCNETSVR 1.1 

Первая строка «HELLO» - это то, что я набрал, вторая - ответ.

ответ

7

Возможно, вам необходимо прекратить действие вашего msg с помощью каких-либо «символов конца строки» - возможно, \r\n, возможно, только одного из двух. Когда вы находитесь в telnet, не завершаете ли вы свой текст, нажав клавишу Return или Enter? В коде Python вы не выполняете эквивалент этого.

+0

сказочный, трюк! Я раньше пытался \ n (не работал), но не знал о \ r. флеш тоже не требовался. благодаря! – mix

+1

оказалось, мне нужен был \ r \ n, а не только \ r. \ r работает в некоторых случаях, но не во всех, что путано. \ n сам по себе не работал. – mix

0

Необходимо, чтобы flush сокет сразу после send, чтобы заставить стек TCP фактически отправлять данные. В противном случае он будет ожидать больше данных для отправки, чтобы эффективно заполнять пакет. Пока вы ожидаете ответа с сервера, на самом деле ничего не отправлено.

+0

Я попробовал флеш() в версии файла объекта без изменений в поведении. Кажется, что не существует метода flush() для сокета, который работает с socket.write (?). – mix

Смежные вопросы