2013-07-23 2 views
5

Kullanarak soketin bağlantısı kesildiğinde algılamayı seçme İstemcinin select() işleviyle bağlantısı kesildiğinde algılamaya çalışıyorum. Sorun şu ki, select() 'nin nasıl çalıştığını pek anlamış değilim. Aşağıdaki kodu kullanıyorum, yanlış yaptığımı ve/veya istemcinin bağlantısının kesildiğini nasıl anlayabileceğimi söyler misiniz? Bloke olmayan prizler kullanıyorum. Bir yuva kapattığındaSelect()

int Network::bytesAvailable() 
{ 
    long bytes = 0; 

    if(ioctl(this->sockfd, FIONREAD, &bytes) < 0) 
    { 
     printf("ERROR: Network:bytesAvailable: ioctl() call failed.\n"); 
     return -1; 
    } 

    return bytes; 
} 

NetworkStatus Network::status() 
{ 
    struct timeval tv; 
    fd_set fd; 
    int result = 0; 

    tv.tv_sec = 5; 
    tv.tv_usec = 0; 

    FD_ZERO(&fd); 
    FD_SET(this->sockfd, &fd); 

    result = select(this->sockfd + 1, &fd, 0, 0, &tv); 

    if(result && !this->bytesAvailable()) 
    { 
     return -1; // disconnected, I'm guessing this is definitely WRONG. 
    } 
    else if(result > 0 && FD_ISSET(this->sockfd, &fd)) 
    { 
     return 1; // bytes available. 
    } 
    else if(!result) 
    { 
     return 0; // timeout 
    } 

    return -1; // select() call failed. 
} 
+0

Genel olarak, bağlantının olup olmadığını tespit ediyoruz? 'keepalive' ve' select() 'yi kullanarak çoğullama için kullanırız. ** doğru değil mi? –

+0

Dilbilgisini anlamıyorum, affedersiniz :) – user2399415

+0

Üzgünüm İngilizce'm çok kötü :(ama yorumunu düzenledim, şimdi anladım mı? –

cevap

8

o "okunabilir" olur ama recv arayarak 0 bayt dönecektir. select'u kullanarak soketin ne zaman okunabileceğini anlayabilirsiniz, daha sonra recv 0 değerini döndürürse, kapattığını bilirsiniz.

Yorumunuz "bayt kullanılabilir" tam olarak doğru değil. Yuva okunabilir, ancak kapalıysa, bayt bulunmaz. engellenmeyen soketlerinin

else if(result > 0 && FD_ISSET(this->sockfd, &fd)) 
{ 
    return 1; // bytes available. 
} 

, recv dönüş 1 ve hiçbir veri ve yuva kapatılmadığında EWOULDBLOCK (veya EAGAIN) için errno ayarlayacaktır.

+0

AFAIK blokajsız soketlerdeki Bu doğru değil, çünkü recv 0'a dönebilir (henüz veri alınmadı). – user2399415

+0

Bloke olmayan soketlerle ilgili düzenlememi kontrol et. –

+0

Teşekkürler. Sorun çözüldü. – user2399415