c ++发送UDP广播

时间:2016-04-06 08:12:35

标签: c++ sockets udp broadcast

对于一个项目,我需要每秒向87.255.255.255发送UDP广播,并使用我的项目值发送端口4448。我用c ++编写了一些代码,但我总是得到错误:

断言`:: bind(s,(sockaddr *)& si_me,sizeof(sockaddr))!= - 1'失败

这一行:

//assert(::bind(s, (sockaddr *)&si_me, sizeof(sockaddr))!=-1);

当我删除此行时,代码会运行,但我在wireshark上找不到任何内容。

是否有人有解决方案或一些额外信息来构建广播发送者?

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <assert.h>
#include <string.h>
#include <ctime>

int main(int argc, char const *argv[]) {

  sockaddr_in si_me, si_other;
  int s;
  printf("Making socket\n");
  assert((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))!=-1);
  fprintf(stderr,"usage %s hostname port\n", argv[0]);
  int port=4448;
  int broadcast=1;
  setsockopt(s, SOL_SOCKET, SO_BROADCAST,
        &broadcast, sizeof broadcast);

        memset(&si_me, 0, sizeof(si_me));
        si_me.sin_family = AF_INET;
        si_me.sin_port = htons(port);
        si_me.sin_addr.s_addr = INADDR_ANY;

  assert(::bind(s, (sockaddr *)&si_me, sizeof(sockaddr))!=-1);

  while(1)
  {
     printf("Send message to broadcast\n");
     char buf[10000];
     strcpy(buf, "test for wireshark");
     unsigned slen=sizeof(sockaddr);
     send(s, buf, sizeof(buf)-1, 0);
     //recvfrom(s, buf, sizeof(buf)-1, 0, (sockaddr *)&si_other, &slen);
     printf("recv: %s\n", buf);
     sleep(1);
  }
}

2 个答案:

答案 0 :(得分:3)

显然,UNIX下的广播有些奇怪。所以这可能会或可能不会按预期工作。

void errno_abort(const char* header)
{
    perror(header);
    exit(EXIT_FAILURE);
}

int main(int argc, char* argv[])
{
#define SERVERPORT 4567
    struct sockaddr_in send_addr, recv_addr;
    int trueflag = 1, count = 0;
    int fd;
    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
        errno_abort("socket");
#ifndef RECV_ONLY
    if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
                   &trueflag, sizeof trueflag) < 0)
        errno_abort("setsockopt");

    memset(&send_addr, 0, sizeof send_addr);
    send_addr.sin_family = AF_INET;
    send_addr.sin_port = (in_port_t) htons(SERVERPORT);
    // broadcasting address for unix (?)
    inet_aton("127.255.255.255", &send_addr.sin_addr);
    // send_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
#endif // ! RECV_ONLY

#ifndef SEND_ONLY
    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
                   &trueflag, sizeof trueflag) < 0)
        errno_abort("setsockopt");

    memset(&recv_addr, 0, sizeof recv_addr);
    recv_addr.sin_family = AF_INET;
    recv_addr.sin_port = (in_port_t) htons(SERVERPORT);
    recv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(fd, (struct sockaddr*) &recv_addr, sizeof recv_addr) < 0)
        errno_abort("bind");
#endif // ! SEND_ONLY

    while ( 1 ) {
#ifndef RECV_ONLY
        char sbuf[256] = {};
        snprintf(sbuf, sizeof(sbuf), "Hello(%d)!", count++);
        if (sendto(fd, sbuf, strlen(sbuf)+1, 0,
                   (struct sockaddr*) &send_addr, sizeof send_addr) < 0)
            errno_abort("send");
        printf("send: %s\n", sbuf);
        usleep(1000000/2);
#endif // ! RECV_ONLY

#ifndef SEND_ONLY
        char rbuf[256] = {};
        if (recv(fd, rbuf, sizeof(rbuf)-1, 0) < 0)
            errno_abort("recv");
        printf("recv: %s\n", rbuf);
#endif // ! SEND_ONLY
    }
    close(fd);
    return 0;
}

希望这会有所帮助。祝你好运。

答案 1 :(得分:0)

发送大小为10000的UDP数据包可能是一个坏主意。 在调用send()时尝试使用strlen(缓冲区)。这可能是你在鲨鱼身上看不到任何东西的原因。

要找到bind()失败的原因,您需要eval errno。

BTW:我记得有一个TCP堆栈实现,它不喜欢IPPROTO_UDP作为socket()调用的第三个参数,即使它应该按照标准工作。请尝试使用0。

相关问题