2013-09-02 11 views
7

Ho un'app per iPad in cui sto creando e collegando un posix socket. Le chiamate a connect(...) non rispondono come previsto quando il dispositivo remoto rifiuta il tentativo di connessione.socket connect() restituisce 0 anche dopo reset peer

Un esempio semplificato di come sto creando e collegando il socket:

struct sockaddr_in server; 
server.sin_family = AF_INET; 

int socket = socket(AF_INET, SOCK_STREAM, 0); 
if(socket < 0) 
{ 
    NSLog(@"socket create failed: %s", strerror(errno)); 
} 
else if(inet_aton(mAddress, &server.sin_addr)) 
{ 
    server.sin_port = htons(mPortNumber); 
    if(connect(socket, (struct sockaddr *)&server, sizeof(server)) == -1) 
    { 
    NSLog(@"connect() failed: %s", strerror(errno)); 
    } 
    else 
    { 
    NSLog(@"connect() succeeded"); 
    } 
} 

In molti casi, l'esempio precedente funziona: ad esempio per un dispositivo remoto (di seguito denominato "il server") che accetta le connessioni, connect() restituisce 0 come previsto. Per un indirizzo inesistente, i blocchi connect() per un po 'restituiscono -1 e errno è ETIMEDOUT.

Dalla documentazione, se il server rifiuta il tentativo di connessione mi aspetterei connect() di tornare -1 e per errno essere ECONNREFUSED o forse ECONNRESET. Invece, connect() restituisce 0.

ho WireSharked la conversazione TCP più volte e posso confermare che sempre e solo si compone di due pacchetti:

client (iPad) -> Server: SYN, ACK

Server -> Client (iPad) : RST, ACK

Perché il collegamento di ritorno 0?

Aggiornamento: connessione allo stesso server da un client diverso, ad es. Qt su Windows (winsock?) O Mac OSX (anche posix) funziona come previsto: il connect() restituisce -1, ECONNREFUSED. Questo mi porta a credere che si tratti di un problema con l'estremità dell'iPad piuttosto che con il server.

+0

"* ... se il dispositivo remoto rifiuta il tentativo di connessione ... *" Sono non sono sicuro se 'to reject' sia un ben definito interms di azione della configurazione della connessione tcp/ip, quindi potresti voler approfondire la tua definizione. – alk

+0

Quello che intendo per "connessione rifiutata" è uno con una conversazione TCP come quella precedente, cioè il client prova a "SYN" e il server risponde con un 'RST'. Quale terminologia useresti per descrivere questo? – sjwarner

+0

Nessun 'SYN-ACK' dal telecomando in risposta al SYN dell'iPad? – alk

risposta

1

Penso che dovresti creare il socket in questo modo, nota il terzo parametro.

socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 

Alla fine della giornata, non importa che connect() restituisca 0 per la connessione rifiutata. Considera questo: supponiamo che connect() abbia esito positivo, che la connessione TCP sia stabilita e che la chiamata restituisca 0. Tuttavia, il server si reimposta o disconnette immediatamente prima che il codice abbia modificato per chiamare scrivere o leggere sul socket. La prossima scrittura fallisce con EPIPE e legge i resi 0. È comunque necessario gestire questo caso.

presumo che hai letto questo, ma è da notare che sono più avvertimenti in utilizzando i socket POSIX in iOS: https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/CommonPitfalls/CommonPitfalls.html

Problemi correlati