2013-11-07 3 views
0

Мне нужен мой сервер для трансляции сообщения (не это важно, но оно содержит информацию о его IP-порте). То, что у меня есть в настоящее время, - это рабочий серверный трансляции, код ниже. Я не уверен в настройке клиента, потому что обычно я бы использовал IP/порт сервера, который у клиента нет, пока он не получит трансляцию. Клиент никогда ничего не получает. Может кто-нибудь сказать мне, что не так.C - Сервер транслирует IP для клиента

Сервер:

struct sockaddr_in server, bcast; 
int sockfd; 
int blen = sizeof(bcast); 
int svrlen = sizeof(server); 
char buf[BUFLEN]; 
if((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){ 
    printf("Socket error.\n"); 
    exit(1); 
} 

int broadcastPermission = 1; 
if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (void *)&broadcastPermission,sizeof(broadcastPermission)) < 0){ 
     printf("Error setting socket options."); 
} 

memset(&bcast, 0, sizeof(bcast)); 
bcast.sin_family = AF_INET; 
bcast.sin_port = htons(PORT); 
bcast.sin_addr.s_addr = htonl(INADDR_ANY); 

string bcastIP = BCASTIP; 
if(inet_aton("255.255.255.255", &bcast.sin_addr) == 0){ 
    printf("Broadcast Address error."); 
    exit(1); 
} 

if (bind(sockfd, (struct sockaddr*)&server, sizeof(server)) == -1){ 
    printf("Port error.\n"); 
    exit(1); 
} 

fflush(stdout); 
if(int bytes = sendto(sockfd, ipinfo, sizeof(ipinfo), 0, (struct sockaddr*)&bcast, blen) == -1){ 
    printf("Broadcast send error."); 
} 
else{ 
    printf("Sent"): 
} 

Клиент:

struct sockaddr_in server; 
int sockfd; 
int bytes; 
int svrlen = sizeof(server); 
char buf[BUFLEN] 
if((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){ 
     printf("Socket error.\n"); 
     exit(1); 
} 

memset((char *)&server, 0, sizeof(server)); 
server.sin_family = AF_INET; 
server.sin_port = htons(BPORT); 
server.sin_addr.s_addr = htonl(INADDR_ANY); 

while(1){ 
    printf("Waiting for broadcast...\n\n"); 
    fflush(stdout); 
    memset(buf,0,BUFLEN); 
    bytes = recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&server, (socklen_t*)&svrlen); 
    printf("Received"); 
} 

ответ

1

Ваш клиент не вызывая связывания() на сокет, прежде чем пытаться получить данные.

http://cs.baylor.edu/~donahoo/practical/CSockets/code/BroadcastReceiver.c показывает следующий пример, который вы можете найти полезным:

void DieWithError(char *errorMessage); /* External error handling function */ 

int main(int argc, char *argv[]) 
{ 
    int sock;       /* Socket */ 
    struct sockaddr_in broadcastAddr; /* Broadcast Address */ 
    unsigned short broadcastPort;  /* Port */ 
    char recvString[MAXRECVSTRING+1]; /* Buffer for received string */ 
    int recvStringLen;    /* Length of received string */ 

    if (argc != 2) /* Test for correct number of arguments */ 
    { 
     fprintf(stderr,"Usage: %s <Broadcast Port>\n", argv[0]); 
     exit(1); 
    } 

    broadcastPort = atoi(argv[1]); /* First arg: broadcast port */ 

    /* Create a best-effort datagram socket using UDP */ 
    if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) 
     DieWithError("socket() failed"); 

    /* Construct bind structure */ 
    memset(&broadcastAddr, 0, sizeof(broadcastAddr)); /* Zero out structure */ 
    broadcastAddr.sin_family = AF_INET;     /* Internet address family */ 
    broadcastAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ 
    broadcastAddr.sin_port = htons(broadcastPort);  /* Broadcast port */ 

    /* Bind to the broadcast port */ 
    if (bind(sock, (struct sockaddr *) &broadcastAddr, sizeof(broadcastAddr)) < 0) 
     DieWithError("bind() failed"); 

    /* Receive a single datagram from the server */ 
    if ((recvStringLen = recvfrom(sock, recvString, MAXRECVSTRING, 0, NULL, 0)) < 0) 
     DieWithError("recvfrom() failed"); 

    recvString[recvStringLen] = '\0'; 
    printf("Received: %s\n", recvString); /* Print the received string */ 

    close(sock); 
    exit(0); 
} 
+0

Я надеялся избежать вызова bind(), но если нужно, я должен. –

0

мне нужен сервер для передачи сообщения (не то, что это имеет значение, но оно содержит его IP/порт данные).

Это похоже на обнаружение службы. Для этого вам действительно нужно использовать стандартный протокол mDNS/Zeroconf. Вы можете использовать библиотеку Avahi для этого (или использовать службу Avahi в Linux или Zeroconf на MacOS X).

Смежные вопросы