マルチ クライアント - ワン サーバーのクイズ アプリケーションを作成したいと考えています。これでは、まず、クライアントがサーバーに接続し、自分自身を登録します。次に、サーバーは、サーバーに登録したすべてのクライアントに質問をマルチキャストします。その後、クライアントは応答で応答し、サーバーにのみ送信されます。そして、サーバーは各クライアントのスコアをそれぞれのクライアントに送信します。
これは私
が上記のアプリケーションでやろうとしていることです. 次に、グループを作成するためにIPアドレスを使用しています(サーバーがマルチキャストする先)。次に、を使用して、クライアントをこのグループに追加して、質問を受け取ることができるようにします。multicast
SOCK_DGRAM
CLASS-D
setsockopt
2.すべてのクライアントからの回答を聞きたいので、 を利用しようと考えていselect
ました。ソケット記述子を使用して、さまざまなクライアントから選択し、どれが読み取りの準備ができているかを認識します。
しかし、問題は、SOCK_DGRAM ソケットを使用しているときにlisten
、accept
機能しないことです。したがって、ソケット記述子 (によって返されるaccept
) を取得しません。そのため、使用できませんselect
(ファイル記述子のみを使用するため)。
では、UDP 機能 (マルチキャスティング) と TCP 機能 (各接続のソケット記述子) を使用したいので、どのように進めればよいでしょうか。
3 に答える
UDP と接続されていないソケットを使用している場合でも、 などの機能を引き続き使用できますselect
。サーバー ソケットをアドレスにバインドし、そのソケットを に使用するだけですselect
。ソケットが読み取り可能な場合、クライアントは eg で何かを送信し、egsendto
を実行できますrecvfrom
。
ただし、TCP ソケットを使用することを強くお勧めします。これにより、特に通信プロトコルに関しては、多くのことが簡単になります (UDP パッケージが失われたり、順序が狂ったりする可能性があることに注意してください。自分で処理する必要があります)。
あなたは正しい軌道に乗っていますが、listen() または accept() は必要ありません。読みやすいように選択してください。ソケットが読み取り可能になったら、それを読み取ります。これにはおそらく select() はまったく必要ありません。実際には、必要に応じてタイムアウトを使用して読み取りをブロックするだけです。
あなたが言ったようselect
に、サーバー側にはソケットが1つしかないので、ここでは役に立ちません。このソケットは、データグラムを送信するために使用されますsendto
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
でdest_addr
、データグラムの宛先アドレスを指定します。
recvfrom(2)
UDP ソケットでの使用も同様です。
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
src_addr
は送信者アドレスであるため、応答を送信したクライアントを識別できます。
recvfrom
呼び出しは、データが読み取り可能になるまでブロックされます (ソケットをブロック解除に設定しない限り)。
ループしてすべての応答を受け取ることができます。