0

UDPソケットを使用して、多くのクライアントを1つのサーバーに接続しています。recvfrom()クライアントのログインパケットを送信した後、次struct addrinfo *のように配列に格納します。

struct addrinfo * userAddrs[64];

recvfrom(sockfd, req, 4096, 0, serverAddr->ai_addr, &serverAddr->ai_addrlen);
userAddrs[userindex] = (struct addrinfo *) malloc(sizeof(struct addrinfo));
memcpy(userAddrs[userindex], serverAddr, sizeof(struct addrinfo));

次に、サーバーはクライアントからメッセージを受信し、そのチャネルの全員に送信します。

// user x channel matrix. 1 means listening on that channel.
int userchannel_matrix[64][64];
for(int i = 0; i < 64; i++){
    if(userchannel_matrix[i][channelindex] == 1){
       sendto(sockfd, &textsay, sizeof (struct text_say), 0, userAddrs[i]->ai_addr, userAddrs[i]->ai_addrlen);
    }
}

ただし、これにより、すべてのメッセージが1つのクライアントに送信されることになります。例:3つのクライアントがチャネル4にサブスクライブしていて、そのうちの1つがメッセージを送信した場合、そのクライアントは、各クライアントが1つを受信するのではなく、3つすべてのメッセージを受信します。私はここで何が間違っているのですか?

4

2 に答える 2

2

基本的な問題は、structaddrinfoにstructsockaddrへのポインターが含まれていることです。これは、明らかに1回だけ初期化されています。したがって、すべてのrecvfrom()は同じsockaddrデータ(addrinfo.ai_addr)を上書きし、すべてのuserAddr[]アイテムは同じデータを指します。

@Troyが提案したように、structsockaddrを使用する必要があります。または、最初に配列内のすべてのaddrinfo構造体を割り当て、それぞれに独自のstruct sockaddr*ai_addrポインターを割り当てます。

于 2012-10-29T00:44:11.107 に答える
1

他の人が言ったことに加えて、あなたが実装しているのは基本的に手動マルチキャストなので、代わりに実際のマルチキャストを使用しないのはなぜですか?このようにして、サーバーは単一のメッセージを単一のマルチキャストIPグループに `sendto()することができ、OSはそのマルチキャストIPグループにサブスクライブしているすべてのクライアントへのメッセージのコピーの送信を処理します。

于 2012-10-30T05:10:01.437 に答える