2014-11-28 3 views
0

문제는 다음과 같습니다. LAN상의 네트워크 서비스 세트를 식별하고 싶습니다. 나는 모든 수있는 장치가 나는 다음 첫 번째 테스트를 썼다을 식별하기 위해 포트 60128.상의 UDP 브로드 캐스트 메시지에 응답 것을 알고 :C의 localhost에서 UDP 브로드 캐스트 수신을 피하십시오.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <errno.h> 
#include <netdb.h> 
#include <sys/socket.h> 
#define BUFLEN 256 
int main(int argc, const char *argv[]){ 
    struct sockaddr_in myaddr, remaddr; 
    int fd, i, slen=sizeof(remaddr); 
    char buf[BUFLEN]; /* message buffer */ 
    int recvlen;  /* # bytes in acknowledgement message */ 
    /* create a socket */ 
    if ((fd=socket(AF_INET, SOCK_DGRAM, 0))==-1) 
    printf("socket created\n"); 
    int broadcast=1; 
    if (setsockopt(fd,SOL_SOCKET,SO_BROADCAST, &broadcast,sizeof(broadcast))==-1) { 
    printf("%s",strerror(errno)); 
    return -1; 
    } 
    unsigned char v2 = 0; 
    if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &v2, sizeof(v2)) == -1){ 
    printf("%s",strerror(errno)); 
    return -1; 
    } 
    /* bind it to all local addresses*/ 
    memset((char *)&myaddr, 0, sizeof(myaddr)); 
    myaddr.sin_family = AF_INET; 
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    myaddr.sin_port = htons(60128); 

    if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) { 
    perror("bind failed"); 
    return 0; 
    }   

    /* Prepare Broadcast */ 
    memset((char *) &remaddr, 0, sizeof(remaddr)); 
    remaddr.sin_family = AF_INET; 
    remaddr.sin_port = htons(60128); 
    remaddr.sin_addr.s_addr = htonl(INADDR_BROADCAST); 

    char *packet = "Test"; 
    size_t plen = strlen(packet); 

    /* now let's broadcast the messages */ 
    if (sendto(fd, packet, plen, 0, (struct sockaddr *)&remaddr, slen)==-1) { 
    perror("sendto"); 
    exit(1); 
    } 
    while(1) { 
    fd_set fdset; 
    FD_ZERO(&fdset); 
    FD_SET(fd, &fdset); 
    struct timeval tv_timeout = { 5 , 0 }; 
    int select_retval = select(fd+1, &fdset, NULL, NULL, &tv_timeout); 
    printf("select: %d\n", select_retval); 
    if (select_retval < 0) { 
     printf("Error\n"); 
     break; 
    } 
    if (select_retval == 0) { 
     printf("No additional response\n"); 
     break; 
    } 
    if (FD_ISSET(fd, &fdset)) { 
     recvlen = recvfrom(fd, buf, BUFLEN, 0, (struct sockaddr *)&remaddr, &slen); 
     if (recvlen >= 0) { 
         buf[recvlen] = 0; 
         printf("received message(%s): \"%s\"\n",inet_ntoa(remaddr.sin_addr),buf); 
       } 
    } 
    } 
    close(fd); 
    return 0; 
} 

지금 나는 다음을 얻을 프로그램을 시작하면 다음의 모든 답변을 가능 장치 은 프로그램 자체의 대답입니다. 내 컴퓨터는 다음 IP "192.168.0.102"을 가지고 있다고 가정하자 (서비스에 필요한 데몬이 내 PC에서 실행되지는 않지만) 출력에 포함됩니다 다음 필터링 할 수있는 방법이 있나요

received message(192.168.0.102): "Test" 

발신자의 IP가 내 자신의 IP인지 확인하기 위해 각 답변을 별도로 확인하지 않고 브로드 캐스트를 보낸 사람?

+0

중복 가능성 : I '는 부호 숯 V2 = 0을 첨가 https://stackoverflow.com/questions/1762101/how-to-ignore-your-own-broadcast-udp-packets – Michael

답변

0

이것을 '루프백'이라고하며이 기능을 사용하지 않으려면 setsockopt() 옵션이 있습니다.

+0

; \t if (setsockopt (fd, IPPROTO_IP, IP_MULTICAST_LOOP, & v2, sizeof (v2)) == -1) { \t \t printf ("% s", strerror (errno)); \t \t return -1; \t} '브로드 캐스트 플래그를 설정하고 난 후에도 동일한 결과를 얻으므로 아무 것도 변경되지 않고 프로그램이 여전히 자체 패킷을 수신합니다. –

관련 문제