我正在尝试读取带有参数(例如指向IP数据包及其大小的char指针)的IP / RAW套接字数据包,并将其放入WRONLY模式下的队列中,并在RDONLY模式下从队列中检索相同的参数。我正在使用结构来发送和接收message(msg)。发送msg时,两个参数都成功放入队列中,但是在检索时会返回分段错误。我的发送和接收文件如下:
mq_send.c
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<mqueue.h>
#include<errno.h>
#include<netinet/ip_icmp.h>
#include<netinet/udp.h>
#include<netinet/tcp.h>
#include<netinet/ip.h>
#include<netinet/in.h>
#include<netinet/if_ether.h>
#include<net/ethernet.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/ioctl.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
#include"external.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) \
struct sockaddr_in source,dest;
int tcp=0,udp=0,icmp=0,others=0,igmp=0,total=0,i,j;
struct mymsg
{
char buff[MAX_SIZE];
int size;
};
int main(int argc, char **argv)
{
mqd_t mq;
struct mymsg m;
struct mq_attr attr;
//char buff[MAX_SIZE];
unsigned char* buffer = (unsigned char*) malloc(sizeof(65536));
int saddr_size,sock_raw;
struct sockaddr saddr;
int data_size;
attr.mq_flags = 0;
attr.mq_maxmsg = 10;
attr.mq_msgsize = MAX_SIZE;
attr.mq_curmsgs = 0;
mq = mq_open(QUEUE_NAME, O_CREAT | O_WRONLY, 0644, &attr);
CHECK((mqd_t)-1 != mq);
memset(buffer, 0, MAX_SIZE);
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(m.buff,buffer,65536);
m.size=data_size;
//char *a="hi";
//CHECK(0 <= mq_send(mq, (char *)&a, MAX_SIZE, 0));
CHECK(0 <= mq_send(mq, (char *)&m, MAX_SIZE, 0));
printf("Packet msg:%s size:%d\n",buffer,data_size);
printf("Sent msg:%s size:%d\n",m.buff,m.size);
ProcessPacket(m.buff , m.size);
CHECK((mqd_t)-1 != mq_close(mq));
close(sock_raw);
return 0;
}
mq_receive.c
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<mqueue.h>
#include<errno.h>
#include<netinet/ip_icmp.h>
#include<netinet/udp.h>
#include<netinet/tcp.h>
#include<netinet/ip.h>
#include<netinet/in.h>
#include<netinet/if_ether.h>
#include<net/ethernet.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/ioctl.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
#include"external.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) \
struct sockaddr_in source,dest;
int tcp=0,udp=0,icmp=0,others=0,igmp=0,total=0,i,j;
typedef struct mymsg
{
unsigned char *buff;
int size;
}msg;
int main(int argc, char *argv[])
{
mqd_t mq;
msg *m=(msg *)malloc(sizeof(msg));
m->buff=(unsigned char*) malloc(sizeof(MAX_SIZE));
int data_size;
mq = mq_open(QUEUE_NAME, O_RDONLY);
CHECK((mqd_t)-1 != mq);
memset(m->buff, 0, MAX_SIZE+1);
ssize_t bytes_read;
bytes_read = mq_receive(mq, (char *)m, MAX_SIZE, NULL);
CHECK(bytes_read >= 0);
printf("Received buff:%s size:%d\n", m->buff,m->size);
//ProcessPacket(m.buff , data_size);
/* cleanup */
CHECK((mqd_t)-1 != mq_close(mq));
CHECK((mqd_t)-1 != mq_unlink(QUEUE_NAME));
return 0;
}
mqueue_send.c的输出:
bcg @ BCGA53:〜/ Desktop / mqueue $ sudo ./mq_send
数据包msg:...大小:60
发送消息:�����M���大小:60
mq_receive.c的输出:
bcg @ BCGA53:〜/ Desktop / mqueue $ sudo ./mq_receive
分段故障
最佳答案
unsigned char* buffer = (unsigned char*) malloc(sizeof(65536));
上面的代码分配了可以容纳
sizeof(65536)
字节的内存。问题在于sizeof(65536)
与sizeof(int)
相同,通常为4个字节,或者可能为8个字节。您要么应该使用此:
unsigned char* buffer = (unsigned char*) malloc(sizeof(char[65536]));
或这个
unsigned char* buffer = (unsigned char*) malloc(65536);
还有其他错误-例如,您应该在
MAX_SIZE
中使用mq_send()
。错误的根本原因是上面概述的问题。实际上,这种分配是没有意义的(至少在上面提供的代码中),因为您可以直接将其接收到消息结构中-那时您将不会看到此问题。