2011-11-16 15 views
1

シンプルなソケットプログラム(サーバー/クライアント)があります。 サーバはWindows上で動作しており、クライアントはcソケットで作られた共有ライブラリを含むAndroidアプリです。getpeernameは確立された接続を認識できません。

クライアント側で、フリーズしないようにしました。connect()関数を渡した後、BLOCKソケットへのロールバックよりもソケットをNON_BLOCKに変更しました。その後、getpeername()を使って検索接続を利用できます。以下のように

...

flags = fcntl(sock, F_GETFL, 0); 
fcntl(sock, F_SETFL, flags|O_NONBLOCK); 

nRet = connect(sock, (struct sockaddr*)&addr, sizeof(addr)); 
if (nRet < 0) 
    if (errno != EINPROGRESS && errno != EWOULDBLOCK) 
     return ERR_CONN; 

... 
... 

nRet = select(sock+1, &readset, &writeset, NULL, &tv); 
if (nRet == 0) 
    if (errno != EINPROGRESS && errno != EWOULDBLOCK) 
     return ERR_SELECT; 

nRet = getpeername(sock, (struct sockaddr*)&addr, &len); 
if (nRet != 0) 
    return ERR_GETPEER; 

fcntl(sock, F_SETFL, flags); 

すべてがうまく働いています。 3Gモードでの作業を除きます。

サーバが接続してもgetpeername()のクライアント側のエラーを返すことがあります。 エラーコードはENOTCONNです。

これを避けるにはどうすれば実装する必要がありますか?どんな提案もありがたいです。 thxを事前に入力してください。


何か問題が見つかりました。

最初に、戻ってくる前にconnect()を渡してからBLOCKソケットにロールバックする必要があります。 秒、それはselect()がtimevalを保持することを保証していないようだ、私はGetTickCount()のような関数をループをブレークするためにカウントされた時間よりも作った。

ここに私のソリューションです。

fcntl(O_NONBLOCK); 
connect(); 
fcntl(BLOCK); 

while (true) 
{ 
    fd_set rdfs, wdfs; 
    FD_ZERO(&rdfs); FD_ZERO(&wdfs); 
    FD_SET(sock, &rdfs); FD_SET(sock, &wdfs); 

    tv.tv_sec = 0; tv.tv_usec = 100; 
    nRet = select(sock + 1, &rdfs, &wdfs, NULL, &tv); 
    if (nRet == -1) return -1; 
    else if (nRet) 
    { 
     nRet = getpeername(); 
     if (!nRet) 
      break; 
    } 

    if (get_tick_count() - delay > timeout) 
     return -2; 
} 

thx! sarnold、カフェ:)

+0

は、あなたの '(2)'実際 'で' sock'を返す]を選択しましたreadset'? – sarnold

+0

あなたはFD_ISSETをチェックしましたか? – JayMuzie

+0

はい、それは正確です; 'FD_ISSET(3)に表示されているソケットでは、読み込みのような操作を試みるべきです。(FD_ISSETの前にFD_ISSETをチェックしていませんでした。 ) 'をあなたの' readset'出力変数に置き換えます。 – sarnold

答えて

0

ソケットが接続されているかどうかを決定するために、むしろgetpeername()よりgetsockopt()を使用する方が普通である。

int so_error; 
socklen_t len = sizeof so_error; 

getsockopt(sock, SOL_SOCKET, SO_ERROR, &so_error, &len); 

if (so_error == 0) { 
    /* socket is connected */ 
} 
関連する問題