2010-10-27 27 views
1

Friends,Comportement de recv sur un socket TCP non bloquant avant la fin de la connexion

J'ai un socket TCP non bloquant (sous AIX). Quand j'ai essayé de me connecter() j'ai eu EINPROGRESS. Ma question est de savoir si j'appelle recv() avant la fin de la connexion, quel serait le code d'erreur (le plus approprié)?

J'ai vu que, en cas d'échec de la connexion, et que j'appelle recv(), j'ai reçu ECONNREFUSED; signifie que j'ai une erreur correspondant à ma précédente tentative de connexion(). Prenant la même logique, je devrais obtenir EINPROGRESS pour recv(). Ai-je raison dans mon approche? Si oui, cela soulève une autre question - Pourquoi ces codes d'erreur ne sont pas inclus dans les codes d'erreur de recv()?

Répondre

3

J'ai seulement vu EAGAIN retourné dans ce cas, comme vous le verriez dans le cas où il n'y a pas de données à lire. Pour écrire sur une socket non connectée, vous obtenez généralement ENOTCONN, bien que je pense que certaines plates-formes pourraient vous donner EAGAIN.

Voici un script Python trivial pour démontrer:

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 

Pour moi, cela donne: Connect nous a donné (36, 'Opération maintenant en cours') Lire nous a donné (35, « ressources temporairement indisponible ') L'écriture nous a donné (57,' Socket n'est pas connecté ')

Ce sont respectivement EINPROGRESS, EAGAIN et ENOTCONN.

+0

Merci, c'est raisonnable. Je vais attendre quelques réponses de plus, avant d'accepter cela. –

1

Vous travaillez sur un socket non bloquant, ce qui est bien parfait pour revenir EINPROGRESS, qui inculpe que l'établissement de la connexion n'a pas encore fini, cela est documenté dans la page de connexion:

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). 

Vous aura besoin de select/pool pour s'assurer que le socket est accessible en écriture, et obtenir une erreur de SO_ERROR.