0

我需要我的服务器来广播一条消息(这并不重要,但它包含它的 IP/端口信息)。我目前拥有的是工作服务器广播,代码如下。我不确定设置客户端,因为通常我会使用客户端在收到广播之前没有的服务器的 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");
}
4

2 回答 2

1

在尝试接收数据之前,您的客户端没有在套接字上调用 bind()。

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);
}
于 2013-11-07T21:58:33.527 回答
0

我需要我的服务器来广播一条消息(这并不重要,但它包含它的 IP/端口信息)。

这听起来很像服务发现。你真的应该为此使用标准的 mDNS/Zeroconf 协议。您可以为此使用 Avahi 库(或在 Linux 上使用 Avahi 服务或在 MacOS X 上使用 Zeroconf)。

于 2013-11-07T22:01:53.773 回答