0

クライアントが接続を閉じたり失ったりしたときにクライアントのIPを取得するこのコードがあります。

char buffer[80]; 
ssize_t bread;
struct sockaddr_in peer;
socklen_t peer_len;

peer_len = sizeof(peer);

memset(&buffer, 0, sizeof(buffer));

bread = read(connectlist[listnum], buffer, 80);
if (bread < 0)
{

if(getpeername(connectlist[listnum],(struct sockaddr *) &peer, &peer_len) == -1){

        perror("getpeername() failed");
    }
            printf("Connection Reset From IP: %s\n", inet_ntoa(peer.sin_addr));

                _Print_To_File(inet_ntoa(peer.sin_addr));
                    close(connectlist[listnum]);
                        close(connectlist[listnum]);
                            connectlist[listnum] = 0;

}

if(bread == 0)
{
if(getpeername(connectlist[listnum],(struct sockaddr *) &peer, &peer_len) == -1){
        perror("getpeername() failed");
    }
            printf("Connection Closed From IP: %s\n", inet_ntoa(peer.sin_addr));

                _Print_To_File(inet_ntoa(peer.sin_addr));
                    close(connectlist[listnum]);
                            connectlist[listnum] = 0;
}

接続が閉じられたときにクライアントのIPを取得できますが、接続がリセットされたときにクライアントのIPを取得できません。接続のリセット時に 0.0.0.0 を取得します。どうすればこれを修正できますか。ありがとう、

4

2 に答える 2

2

getpeername()接続されたソケットに対してのみ機能します。ソケットが切断されるとENOTCONN、呼び出し時にエラーが発生します。これがgetpeername()、ソケットが接続されているかどうかのチェックとして時々使用される理由です。

于 2012-11-07T17:06:47.993 に答える
1

ingの前に donestruct sockaddrの呼び出しによって返されたを使用することをお勧めします。accept()read()

からの逐語man accept:

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

[...]

引数 addr は、sockaddr 構造体へのポインターです。 この構造体には、通信層で認識されているピア ソケットのアドレスが入力されます。 addr が返すアドレスの正確な形式は、ソケットのアドレスファミリによって決まります (socket(2) およびそれぞれのプロトコルのマニュアルページを参照してください)。addr が NULL の場合、何も入力されません。この場合、addrlen は使用されず、NULL にする必要があります。

于 2012-11-07T16:59:33.590 に答える