UDP broadcast in C

2019-03-31 06:14发布

问题:

When I broadcast a message by the code below, the server on the host machine also receive the message, how can I prevent host machine to receive the message that it sends?

Is it possible to change something on the code or would it be better to use something like if (strcmp(hostIP == IP_of_the_package) == 0) { <discard the msg>}? the host machine gets IP from DHCP, how can I define hostIP as a variable and How can I extract IP addr of the packet?

void boardcast_msg(char *mess){
   int sock;                        
   struct sockaddr_in broadcastAddr; 
   char *broadcastIP;                
   unsigned short broadcastPort;     
   char *sendString;                 
   int broadcastPermission;         
   int sendStringLen;                

   broadcastIP = "255.255.255.255";  
   broadcastPort = 33333;

   sendString = mess;             /*  string to broadcast */


   if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){
       fprintf(stderr, "socket error");
        exit(1);
   }


   broadcastPermission = 1;
   if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *) &broadcastPermission,sizeof(broadcastPermission)) < 0){
       fprintf(stderr, "setsockopt error");
       exit(1);
   }

   /* Construct local address structure */
   memset(&broadcastAddr, 0, sizeof(broadcastAddr));   
   broadcastAddr.sin_family = AF_INET;                 
   broadcastAddr.sin_addr.s_addr = inet_addr(broadcastIP);
   broadcastAddr.sin_port = htons(broadcastPort);       

   sendStringLen = strlen(sendString);  

        /* Broadcast sendString in datagram to clients */
        if (sendto(sock, sendString, sendStringLen, 0, (struct sockaddr *)&broadcastAddr, sizeof(broadcastAddr)) != sendStringLen){
            fprintf(stderr, "sendto error");
            exit(1);
        }

}

回答1:

Disable loopback so you do not receive your own datagrams:

char loopch=0;

if (setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP,
               (char *)&loopch, sizeof(loopch)) < 0) {
  perror("setting IP_MULTICAST_LOOP:");
  close(sd);
  exit(1);
}

from: http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=%2Frzab6%2Frzab6x1multicast.htm



回答2:

You are on the right track, you need to see if a received package is from your self, and then discard it.

The simplest way to get the local hosts address is to use gethostname and gethostbyname. These will however not work well if your host has multiple hostnames or IP addresses. Search SO (or Google) for how to get all possible network addresses.



回答3:

your program's broadcast destination port should be blocked on your machine to avoid receiving self broadcasts.

in your iptables you can drop the (TCP or UDP as required ) packets received on that port.



回答4:

recvfrom will give you an address. Use that.

As for what addresses to match against, on many systems (probably the ones you care about) you can get local IP addresses with getifaddrs. However this is not in POSIX.



标签: c udp broadcast