2016-04-16 5 views
4

Ich bin ein Neuling in C.

Ich habe gerade festgestellt, dass die connect()-Funktion auf der Client-Seite so lange wie die TCP-Drei-Wege-Hand-Shake zurückgeben kann ist fertig. Ich meine connect() kann sogar zurückkehren, bevor die accept() auf der Server-Seite aufgerufen wird (korrigieren Sie mich, wenn ich falsch liege).

Basierend auf diesem Wissen, meine Frage ist, dass, wenn ich select() danach auf der Clientseite aufrufen, und beobachten Sie den Dateideskriptor warten auf es beschreibbar sein, wenn select() erfolgreich zurückgibt, bedeutet dies, dass die Serverseite bereits accept() aufgerufen hat und jetzt Ich kann sicher auf die Serverseite schreiben, oder? Vielen Dank für Ihre Zeit.connect(), accept() und select() happening sequence order

int flags = fcntl(fd, F_GETFL); 

flags |= O_NONBLOCK; 

fcntl(fd, F_SETFL, flags); 

if (connect(fd, (struct sockaddr *)saptr, salen) < 0) 
{ 
    if (errno != EINPROGRESS) 
     /* error_return */ 
} 

fd_set set; 
FD_ZERO (&set); 

FD_SET (fd, &set); 

select (FD_SETSIZE, NULL, &set, NULL, &timeout) 
/* Here, if select returns 1, that means accept() is already called 
    on the server side, and now I can safely write to the server, right? */ 
+1

'Ich meine connect() kann sogar zurückkehren, bevor die accept() auf der Serverseite heißt' - sicher, ja. –

Antwort

-1

'Ich verbinde meine() kann auch vor der Rückkehr accept() auf dem Server Seite wird als'

Ja, es kann, und tut.

, wenn ich wählen Sie() aufrufen, danach auf der Client-Seite, und beobachten Sie die Datei Descriptor zu warten, bis es beschreibbar zu sein, wenn select() erfolgreich zurückkehrt, das heißt, der Server-Seite bereits akzeptieren genannt hat () und jetzt kann ich sicher auf die Serverseite schreiben, oder?

Sicher. Schreiben Sie weg :)

3

wenn select() erfolgreich zurückgibt, dass der Server-Seite bedeutet bereits annehmen()

Nein, nicht unbedingt genannt hat. connect() wird zurückgegeben, wenn der Verbindungsversuch erfolgreich oder fehlgeschlagen ist. Auf der anderen Seite wird dies durch den Netzwerkstapel außerhalb des Anwendungskontextes gehandhabt. Die nachfolgende accept() selbst erzeugt keine zusätzliche Kommunikation.

und jetzt kann ich sicher auf die Serverseite schreiben, richtig?

Es gibt alle Arten von Dingen, die Sie von „sicher“ bedeuten könnte, aber wenn Sie meinen, dass die lokale Seite dann mindestens ein Byte ohne Blockierung schreiben kann ja, select() Versprechen Sie, dass. Was auch immer Sie erfolgreich schreiben, wird über die Leitung an die entfernte Seite gesendet. Abhängig vom Verhalten der Software am Remote-Ende kann es dort für eine gewisse Zeit gepuffert werden. Ob diese Software noch die Verbindung hat oder nicht, ist für diese Frage nicht direkt relevant.

Update: Beachten Sie auch, dass der Netzwerkstapel eine pro-Socket-Warteschlange von etablierten Verbindungen verwaltet, die noch nicht accept() ed (sein Rückstand) sind. Dieses Warteschlangen-Verhalten ist ein Grund, warum ein Server nicht sofort Verbindungen accept(), nachdem sie eingerichtet wurden, insbesondere unter hoher Last.

+0

Gute Antwort. Könnte eine zusätzliche Notiz zu 'listen()' s Backlog berücksichtigen. –

+0

@ John Bollinger Danke für Ihre Antwort. Ich habe gerade ein kleines Experiment zum Testen gemacht. Ja, die Rückgabe von 'select' bedeutet nicht notwendigerweise, dass die Serverseite bereits' accept' aufgerufen hat. – HuangJie