2016-04-06 53 views
0

プロジェクトでは、毎秒UDPブロードキャストを87.255.255.255に、ポート4448をmyプロジェクトの値で送信する必要があります。私はC++でいくつかのコードを書かれているが、私は常にエラーました:!C++ UDPブロードキャストを送信

アサーション `::バインド(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); 
    } 
} 
+0

'assert()'に関数をラップするのは悪い考えです。なぜなら、デバッグがオフになったときにそれらが削除されるからです。 _asserting_の代わりに 'perror()'を呼び出すと、なぜそれが失敗しているのかを知ることができます。 –

+0

私はそれをperrorに変更しようとしましたが、エラーが出ました: 'bool'を 'const char *'に '1'を 'void perror(const char *)'に変換できません。 – josejos41

+0

'if(bind(...) –

答えて

0

明らかに、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; 
} 

これが役立ちます。がんばろう。

0

サイズ10000のUDPパケットを送信することは、おそらく悪い考えです。 send()を呼び出すときにstrlen(バッファ)を代わりに使用してみてください。これはサメに何も見られない理由です。

bind()が失敗する理由を調べるには、errnoを評価する必要があります。

私は、標準に従って動作するはずですが、socket()呼び出しの3番目のパラメータとしてIPPROTO_UDPが嫌いなTCPスタックの実装を覚えています。代わりに0を使用してみてください。

+0

私はバッファを20に変更しました。これは何もしませんが、私はそれをコンパイルするためにアサーションラインを削除する必要があります。 – josejos41

+0

私はIPPROTO_UDPをゼロに変更しましたが、wiresharkを渡すものは何も表示されません。 – josejos41

関連する問題