2011年5月23日 星期一

UDP收送broadcast packets (BSD socket)

之前有用到,所以做一些筆記。
發UDP broadcast的寫法如下,最重要的是setsockopt:
    int sockfd;
    struct sockaddr_in their_addr; // connector's address information
    struct hostent *he;
    int numbytes;
    int broadcast = 1;
    //char broadcast = '1'; // if that doesn't work, try this

if ((he=gethostbyname("255.255.255.255")) == NULL) {  // get the host infoif     perror("gethostbyname");        exit(1);
    }

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    // this call is what allows broadcast packets to be sent:
    if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast,
        sizeof broadcast) == -1) {
        perror("setsockopt (SO_BROADCAST)");
        exit(1);
    }

    their_addr.sin_family = AF_INET;     // host byte order
    their_addr.sin_port = htons(SERVERPORT); // short, network byte order
    their_addr.sin_addr = *((struct in_addr *)he->h_addr);
    memset(their_addr.sin_zero, '', sizeof their_addr.sin_zero);
    if ((numbytes=sendto(sockfd,packet_content, packet_size, 0,
            (struct sockaddr *)&their_addr, sizeof their_addr)) == -1) {
    perror("sendto");
    exit(1);
    }
收UDPbroadcast的寫法如下(註:有時候收不到broadcast,是因為防火牆檔掉的關係):
 另外,如果是bind再某個特定interface下,也會有收不到broadcast packet的問題。
所以要bind再某一個interface,又要收broadcast的寫法如下:
     int broadcast = 1;
    /* Create the UDP socket */
    if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
        Die("Failed to create socket");
    }
    if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast,sizeof broadcast) == -1) {
        perror("setsockopt (SO_BROADCAST)");
        exit(1);
    }
    if(setsockopt(sock,SOL_SOCKET,SO_BINDTODEVICE,"eth0",4)==-1)
    {
        perror("setsockopt (SO_BINDTODEVICE)");
        exit(1);

    }
    /* Construct the server sockaddr_in structure */
    memset(&echoserver, 0, sizeof(echoserver));       /* Clear struct */
    echoserver.sin_family = AF_INET;                  /* Internet/IP */
    //echoserver.sin_addr.s_addr = inet_addr(DHCP_SERVER_IP);
    echoserver.sin_addr.s_addr = htonl(INADDR_ANY);
    echoserver.sin_port = htons(DHCP_PORT);       /* server port */

    /* Bind the socket */
    serverlen = sizeof(echoserver);
    if (bind(sock, (struct sockaddr *) &echoserver, serverlen) < 0) {
        Die("Failed to bind server socket");
    }

        if ((received = recvfrom(sock, buffer, BUFFSIZE, 0,
                        (struct sockaddr *) &echoclient,
                        &clientlen)) < 0) {
            Die("Failed to receive message");
        }

沒有留言:

張貼留言