Ineternet domain stream型通信の場合は、acceptでクライアントと接続する際に クライアント側のIPアドレスとポート番号を調べることができます。
sockaddr_in c_addr; socklen_t len = sizeof(c_addr); int s=accept( sb, (sockaddr*)&c_addr, &len ); fprintf( stderr, "Client IP %s, PORT %u\n", inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port) );
Ineternet domain datagram型通信の場合は、recvfromでデータを受ける際に クライアント側のIPアドレスとポート番号を調べることができます。
sockaddr_in c_addr; socklen_t len = sizeof(c_addr); len = recvfrom( s, &msg, sizeof(msg), 0, (sockaddr*)&c_addr, &len ); msg[len] = '\0'; fprintf( stderr, "Client IP %s, PORT %u\n", inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port) );
Local domain stream型の場合は accept において、 local domain datagram型の場合は recvfrom において クライアントのアドレスを調べることができます。
しかし、ここにUNIX domainソケットのファイル名が得られるのは クライアントが bindを実行して別の UNIX domain ソケットに bind した 場合のみで、普通は空です。sockaddr_un c_addr; socklen_t len = sizeof(c_addr); // in case stream int s = accept( sb, (sockaddr*)&c_addr, &len ); // in case datagram len = recvfrom( s, &msg, sizeof(msg), 0, (sockaddr*)&c_addr, &len ); msg[len] = '\0'; fprintf( stderr, "Client Unix domain socket [%s]\n", c_addr.sun_path );
Internet domain stream型通信の場合には、acceptで接続が完了した後でも 接続中ならいつでも相手の情報を調べることができます。 それにはgetpeername関数をソケットに対して使います。
この関数はサーバー側でも、クライアント側でも実行することができ、 通信回線の相手側のアドレスを得ます。sockaddr_in another_addr; socklen_t len = sizeof(another_addr); getpeername( s, (sockaddr*)&another_addr, &len ); printf("Another IP %s, PORT %u\n", inet_ntoa(another_addr.sin_addr), ntohs(another_addr.sin_port) );
通信回線の自分側のアドレスを得るには getsockname関数を ソケットに対して使います。
sockaddr_in my_addr; socklen_t len = sizeof(my_addr); getsockname( s, (sockaddr*)&my_addr, &len ); printf("My IP %s, PORT %u\n", inet_ntoa(my_addr.sin_addr), ntohs(my_addr.sin_port) );