I am using UDP sockets to connect many clients to one server. After recvfrom()ing a client’s login packet, I store their struct addrinfo * in an array like so:
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));
Then the the server receives messages from clients and sends it to everyone on that channel:
// 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);
}
}
However, this ends up sending all of the messages to one client. Ex: If three clients are subscribed to channel 4 and one of them sends a message, that client will receive all 3 messages instead of each client receiving one. What am I doing wrong here?
The basic problem is that struct addrinfo contains a pointer to a struct sockaddr, which you have clearly only initialized once. So every recvfrom() overwrites the same piece of sockaddr data (addrinfo.ai_addr), and every userAddr[] item points to the same one.
As @Troy suggested, you should be using struct sockaddr. Or else allocate all the addrinfo structures in the array first,, each with its own struct sockaddr *ai_addr pointers.