1

サーバーへの正常な接続を受信して​​おり、コールバック関数を使用しています:

ホストの名前を取得してコンソールに出力しようとしています:

if(theType == kCFSocketConnectCallBack){
        NSLog(@"Connection is accepted");
        CFSocketNativeHandle nativeSocket = CFSocketGetNative(theSocket);
        uint8_t name[SOCK_MAXADDRLEN];
        socklen_t namelen = sizeof(name);
        NSData *peer = nil;
        if (getpeername(nativeSocket, (struct sockaddr *)name, &namelen) == 0) {
            peer = [NSData dataWithBytes:name length:namelen];
            NSString *string = [[NSString alloc] initWithData:peer encoding:NSUTF8StringEncoding];
            NSLog(@"IP adress of connected peer: %@", string);
        } 

アプリケーションをデバッグ モードで実行すると、 name に割り当てられた IP アドレスの値が表示されるので、 name の取得に成功しました。各値は uint8_t です。ピアの長さは 16 を示しています。それを NSData に変換してから NSString に変換する際の問題...

出力: 2010-01-31 13:57:58.671 接続されたピアの IP アドレス: (null)

私の文字列は NULL として出力されています。

アドバイスをいただければ幸いです....

4

3 に答える 3

2

getpeername() はリモート側のホスト名を返しません。アドレスを返します。

$ man getpeername

...

説明
     getpeername() 関数は、接続されているピアのアドレスを返します
     指定されたソケット。

getnameinfo() が必要です:

$ man getnameinfo

...

説明
     getnameinfo() 関数は、sockaddr 構造体を
     ホスト名とサービス文字列のペア。これは、プロの代替品です。
     gethostbyaddr(3) や getservbyport(3) よりも柔軟性が高い
     関数であり、getaddrinfo(3) 関数の逆です。

または gethostbyaddr():

$ man gethostbyaddr

...

説明
     getaddrinfo(3) および getnameinfo(3) 関数は、
     gethostbyname()、gethostbyname2()、および gethostbyaddr() 関数。

     gethostbyname()、gethostbyname2()、および gethostbyaddr() 関数はそれぞれ
     を記述する次の構造を持つオブジェクトへのポインタを返します。
     それぞれ名前またはアドレスで参照されるインターネットホスト。
于 2010-01-31T19:10:41.900 に答える
2

sockaddr文字配列の単なる typedef ではなく、構造体です。getpeernameアドレスを実際の構造体に渡し、その構造体sockaddrのフィールドから文字列を作成する必要があります。これは、実際にはアドレス型の文字列であるとsa_data想定してsa_dataおり、ドキュメントでは実際に信頼できるとは示唆されていません。別の答えが言うように、あなたの目標が文字列表現を取得して印刷することである場合、これはあなたが望む呼び出しではありません。

(また、文字配列から NSString に移動するために NSData はまったく必要ありません。単に使用できます-[NSString initWithBytes:length:encoding:])

于 2010-01-31T21:27:50.183 に答える