2014-01-19 3 views
0

Считайте меня новичком в плане программирования сокетов.Как сообщает сокет TCP/IP, что внешний хост закрыл соединение?

Предположим, я использую Telnet для подключения к веб-серверу:

# telnet localhost 80 
Trying 127.0.0.1... 
Connected to localhost. 
Escape character is '^]'. 
GET/
(blah blah blah) 
connection closed by foreign host. 

Мой вопрос что касается написания приложения, чтобы сделать то же самое. В принципе, я пишу Perl. Но я не думаю, что это особый вопрос Perl.

В Perl я создаю сокет, используя IO :: Socket :: INET, который расширяет IO :: Handle. По сути, сокет имеет те же свойства, что и дескриптор файла, который, как я понимаю, является определением «сокета» в unix-неразличимом от дескриптора файла.

Мое приложение предназначено для сопоставления функций telnet, описанных выше. Я открываю сокет и записываю строку «GET/\ n \ n» и получаю точно такие же результаты, за исключением «соединения, закрытого иностранным хостом». Фактически все свойства сокета выглядят неизменными.

Мой вопрос: В Perl или как-то иначе, как я могу запросить свойства сокета для определения результата, сообщенного через telnet. То есть, как я могу определить, что внешний хост закрыл соединение?

+1

Как правило, результат 'select' или' read' будет сообщать вам, что происходит с сокетом, включая это условие. –

+0

Как отметил @LightnessRacesinOrbit, вы пытаетесь прочитать и поймать исключение или errno. По моему опыту, я всегда получаю SIGPIPE, когда пульт закрывает сокет, пока я пытаюсь его прочитать. – alvits

+0

@alvits Нет, нет. Это происходит только при * письме * или при чтении, если вы ранее писали, пока сверстник уже закрылся, или если пэр закрыл аборт по какой-то другой причине. Обычно вы получаете однозначную индикацию конца потока из потока. То, что это точно зависит от того, какой API вы используете, но не включает SIGPIPE. – EJP

ответ

2

Я не могу говорить за Perl, но в API C Sockets:

  • read() и recv() возвращения нулевого, когда собеседник закрывает соединение и вы прочитали все данные, которые он ранее отправленными.
  • send() и write() в конечном итоге возвратят -1 с errno = ECONNRESET, если вы продолжаете писать соединение, которое уже было закрыто одноранговым узлом.

Существует не «состояние» сокета TCP, которое вы можете запросить независимо от отправки или получения, которое предоставит вам эту информацию.

+0

Если статус можно получить, используя «select» - эта функция реализована на Perl и кажется лучшим ответом. –

+0

+1 Это почти то, как я пишу программы сокетов. Но я буду честен, маленькие советы, подобные этому, многому меня научили. – alvits

+0

@SunnyJim. Только 'readable ',' writable 'и' error 'состояния могут быть определены с помощью' select() '. Конец потока, т. Е. Обычный случай одноранговой развязки, не может. – EJP

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