>>1822 みみ > ・クライアントからの接続がある。 > (sd[i]がインクリメントされる。) > ・接続してきたクライアントからの処理要求がある。 > (ここで、クライアント側のプロセスが何なのかが判明する。) > ・getpeername を行うことで、sd[i]の”i”の値を得る。 > (これにより、接続元クライアントのプロセスとを > リンクさせることができる。) うーん、説明が難しいですね。一度わかってしまえば何てことはない のですが…。 クライアントとサーバとの接続点がソケットです。複数のソケットが あるとき、それらを識別するのはソケットディスクリプタ (3 とか 4 などの整数値) です。別のソケットには、必ず別のソケットディスク リプタが割り振られます。 http://X68000.startshop.co.jp/~68user/net/c-echo-2.html で言うと、 for ( i=0 ; i<FD_SETSIZE ; i++ ){ if ( FD_ISSET(i, &target_fds) ){ if ( i == listening_socket ){ accept して、新クライアントのソケットディスクリプタを取得 } else { ソケットディスクリプタ i からデータが送られてきた } } } という感じです。例えば i==5 のとき FD_ISSET が真ならば、 今からやりとりしたいのは「ソケットディスクリプタ 5」です。 このクライアントとの接続が切れない限り、この番号は不変です。 データを読みたいなら read(5, buf, sizeof(buf)) すればよいし、 データを送りたいなら write(5, "hoge", sizeof("hoge")-1) とします。 if ( i == listening_socket ){ accept して、新クライアントのソケットディスクリプタを取得 } else { len = read(5, buf, sizeof(buf)); write(5, buf, len); } とすれば、それで echo サーバのでき上がりです。ソケット ディスクリプタ 5 からデータを読んで、ソケットディスクリプタ 5 にデータを書いているので、echo した結果が別クライアントに 送られることはありません。 つまり、ソケットがいくつあっても「ソケットディスクリプタが 確定している=クライアントが識別できる」と言えます。 getpeername は、相手側の IP アドレスやポート番号を知りたい 場合に使いますが、根本的にはそれらの情報がなくてもどの クライアントとやりとりしているのか区別できます。 |