2

誰でも、posix mqueue の不正なファイル記述子の問題を解決するのを手伝ってくれます。RAW ソケット パケットを読み取って mqueue に配置しようとしています。

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<mqueue.h>
#include<netinet/ip_icmp.h>   
#include<netinet/udp.h> 
#include<netinet/tcp.h>  
#include<netinet/ip.h>
#include<netinet/if_ether.h>
#include<net/ethernet.h>

#define QUEUE_NAME  "/test_queue"
#define MAX_SIZE    71680



#define CHECK(x) \
    do { \
        if (!(x)) { \
            fprintf(stderr, "%s:%d: ", __func__, __LINE__); \
            perror(#x); \
            exit(-1); \
        } \
    } while (0) \


int main(int argc, char **argv)
{
    mqd_t mq;
    struct mq_attr attr;
    char buff[MAX_SIZE + 1];
    unsigned char* buffer = (unsigned char*) malloc(sizeof(65536));
    int saddr_size , data_size,sock_raw;
    struct sockaddr saddr;

    /* initialize the queue attributes */
    attr.mq_flags = 0;
    attr.mq_maxmsg = 10;
    attr.mq_msgsize = MAX_SIZE;
    attr.mq_curmsgs = 0;

    /* create the message queue */
    mq = mq_open(QUEUE_NAME, O_CREAT | O_RDONLY, 0644, &attr);
    CHECK((mqd_t)-1 != mq);

    sock_raw = socket( AF_PACKET , SOCK_RAW , htons(ETH_P_ALL)) ;
    if(sock_raw < 0)
    {
       perror("Socket Error\n");
       return 1;
    }
    saddr_size = sizeof saddr;
    data_size = recvfrom(sock_raw , buffer ,65536 , 0 , &saddr , (socklen_t*)&saddr_size);

    if(data_size <0 )
    {
       printf("Recvfrom error , failed to get packets\n");
       return 1;
    }

    memcpy(buff,buffer,65536);


    CHECK(0 <= mq_send(mq, buffer, MAX_SIZE, 0));

    printf("Msg sent");

    CHECK((mqd_t)-1 != mq_close(mq));

    return 0;
}

私が得た出力は

main:64: 0 <= mq_send(mq, buffer, MAX_SIZE, 0): 不正なファイル記述子

4

1 に答える 1

3

mq_send読み取り専用 (O_RDONLY) で開いたメッセージ キュー記述子に( ) を書き込もうとしています。

oflags引数を に変更するO_CREAT | O_RDWRと、送信が機能します。

Linux の man ページはこれを呼び出していませんが、他の人はそうしています: EBADF は fd または fd のようなハンドルが完全に無効であること、または要求された操作に対して無効であることを意味する可能性があります。

于 2014-12-12T14:42:42.657 に答える