2012-10-28 100 views
0

我正在使用UDP套接字將許多客戶端連接到一臺服務器。 recvfrom()荷蘭國際集團客戶的登錄數據包後,我存儲他們struct addrinfo *在數組中,像這樣:C:sendto()給多個客戶端 - 所有消息都去同一個客戶端?

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); 
    } 
} 

然而,這最終將所有的消息發送到一個客戶端。例如:如果三個客戶端訂閱了頻道4,其中一個客戶端將收到全部3條消息,而不是每個客戶端接收到的消息。我在這裏做錯了什麼?

+1

你不應該使用sockaddr系列結構嗎? struct addrinfo僅用於getaddrinfo。 – goji

+0

我用我的客戶端的addrinfo發送消息到服務器,它工作正常。我的服務器也可以發送消息給客戶端。 – theeggman85

+2

那麼,你的userAddrs數組和它所包含的數據肯定有問題。你有沒有嘗試打印出演示文稿格式的IP /端口,看看是什麼?同樣在你提供的代碼示例中,我沒有看到userindex被增加。這是否在樣本之外「完成」? – goji

回答

2

基本的問題是,struct addrinfo包含一個指針到一個struct sockaddr,你明確地只初始化了一次。所以每個recvfrom()都會覆蓋同一塊sockaddr數據(addrinfo.ai_addr),並且每個userAddr []項都指向同一個數據。

由於@Troy建議,你應該使用struct sockaddr。否則分配第一個數組中的所有addrinfo結構,,每個都有自己的struct sockaddr * ai_addr指針。

+0

只要您發佈它, ,我忘記了在addrinfo結構中還有指針......謝謝! – theeggman85

1

除了別人說的外,你正在實現的基本上是手動多播,那麼爲什麼不直接使用真正的多播?這樣,您的服務器可以將單條消息發送給單個多播IP組,並且操作系統將處理將消息的副本發送給已訂閱了該多播IP組的每個客戶端。

相關問題