2010-10-27 3 views
1

Друзья,Поведение recv на неблокирующем гнезде TCP до завершения соединения

У меня есть неблокирующий TCP-сокет (в AIX). Когда я попытался подключиться(), я получил EINPROGRESS. Мой вопрос: если я вызову recv() до завершения соединения, каков будет (наиболее подходящий) код ошибки?

Я видел, что в случае сбоя соединения, и я вызываю recv(), я получил ECONNREFUSED; означает, что я получил ошибку, соответствующую моей более ранней попытке connect(). Принимая ту же логику, я должен получить EINPROGRESS для recv(). Я прав в своем подходе?

Если да, возникает другой вопрос: почему такие коды ошибок не включены среди кодов ошибок recv()?

ответ

3

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

Вот тривиальный сценарий Python, чтобы продемонстрировать:

import socket 
# Any address that does not succeed or fail right away will do 
ADDR = "192.168.100.100" 
PORT = 23 
s = socket.socket() 
s.setblocking(False) 
try: 
    s.connect((ADDR, PORT)) 
except socket.error, e: 
    print "Connect gave us",e 
try: 
    s.recv(1) 
except socket.error, e: 
    print "Read gave us",e 
try: 
    s.send("x") 
except socket.error, e: 
    print "Write gave us",e 

Для меня, это дает: Connect нам дал (36, 'Операция в настоящее время прогресс') Read дал нам (35, «Ресурс временно недоступен ') Напишите нам (57, «Гнездо не подключено»)

Это EINPROGRESS, EAGAIN и ENOTCONN соответственно.

+0

Спасибо, это разумно. Я подожду еще несколько ответов, прежде чем принимать это. –

1

Вы работаете на неблокируемый разъем, который идеально подходит отлично вернуться EINPROGRESS, что предъявить обвинение, что установление соединения не достраивает еще, это описано в странице CONNECT в:

EINPROGRESS 
      The socket is nonblocking and the connection cannot be completed immediately. It is possible to select(2) or poll(2) for completion by 
      selecting the socket for writing. After select(2) indicates writability, use getsockopt(2) to read the SO_ERROR option at level SOL_SOCKET 
      to determine whether connect() completed successfully (SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual error codes listed 
      here, explaining the reason for the failure). 

Так вы потребуется выбрать/пул, чтобы убедиться, что сокет доступен для записи, и получить сообщение от SO_ERROR.

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

  • Нет связанных вопросов^_^