如何在c socket程序中将struct变量复制到缓冲区?

时间:2013-11-21 06:30:09

标签: c sockets

在客户端,我需要从网络接收数据包并将其写入一个文件,该文件将被发送到服务器以进行进一步处理。

接收和处理数据包时出现问题,因为我曾经在write()api中只发送一个不是'saddr'的缓冲区和'size'。

因此我使用结构来声明所有成员,例如buffer,saddr,saddr_size。 这是我的data_capture代码:

int logfile;
struct sockaddr_in source, dest;

struct fields{               //edited
  void* b;   
  struct sockaddr *s;
  socklen_t *ssize;
}data; 

int main()
{
  int saddr_size, data_size;
  struct fields data;
  struct sockaddr saddr;

  gopromiscous();

  unsigned char *buffer = (unsigned char *) malloc(1024);

  logfile = open("sniff_data.bin", O_CREAT | O_WRONLY | O_APPEND, 0777);
  if (logfile == -1)
  {
    printf("Unable to create sniff_data file.");
  }
  printf("\n Client Receiving the Packets...\n");

  int sock_raw = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
  setsockopt(sock_raw, SOL_SOCKET, SO_BINDTODEVICE, "eth0", strlen("eth0") + 1);

  if (sock_raw < 0)
  {
    perror("Socket Error");
    return 1;
  }

  int count = 10;
  while (count >= 0)
  {
    count--;
    saddr_size = sizeof saddr;
    //Receive a packet      
    data_size = recvfrom(sock_raw, buffer, 1024, 0, &saddr,
        (socklen_t*) &saddr_size);

    // i have created struct to buffer,saddr and saddr_size above
    if (data_size < 0)
    {
      printf("Recvfrom error , failed to get packets\n");
      return 1;
    }

    //i need to copy the values of buffer, saddr and sddr_size into a variable and      
    //then use that variable in write api 

    strcpy(data.b,buffer);         //edited
    data.s=&saddr;
    data.ssize=(socklen_t*)&saddr_size;

    int cont = write(logfile, &data, data_size);

  }
  printf("\n Done\n");
  close(logfile);
  close(sock_raw);
  return 0;
}

int gopromiscous()
{
  int fd;
  struct ifreq eth;

  fd = socket(AF_INET, SOCK_PACKET, htons(0x800));

  strcpy(eth.ifr_name, "eth0");

  ioctl(fd, SIOCGIFFLAGS, &eth);

  eth.ifr_flags |= IFF_PROMISC;

  ioctl(fd, SIOCSIFFLAGS, &eth);

  printf("\n Entered Promiscuous Mode Successfully\n");
}

我使用strcpy将buffer,sadddr,saddr_size的值复制到一个可以在write api中使用的变量。我的意思是说我想将整个结构复制到缓冲区中,然后在write()中使用它。

数据处理代码是:

   void ProcessPacket(unsigned char* , int);
   void print_ip_header(unsigned char* , int);
   void print_tcp_packet(unsigned char * , int );
   void print_udp_packet(unsigned char * , int );
   void print_icmp_packet(unsigned char* , int );
   void PrintData (unsigned char* , int);

   FILE *logfile;
   int infile;
   struct sockaddr_in source,dest;
   int tcp=0,udp=0,icmp=0,others=0,igmp=0,total=0,i,j;


   int main()
   {
     int saddr_size , data_size;
     struct sockaddr saddr; 

     struct fields{ 
        void* b;   
        struct sockaddr *s;
        socklen_t *ssize;
     }data2; 


  unsigned char *buffer3 = (unsigned char *) malloc(1024);
  char *fname = "/home/shishira/Desktop/packet_capture/info_agent_report_processed.txt";


  infile=open("info_agent_report.txt",O_RDONLY);
  logfile=fopen(fname,"w");

  printf("\n Starting..\n");
  saddr_size = sizeof saddr;

  //Now process the packet
  int totl=1;
  do
  {   
   printf("iteration  %d of processing at taskagent\n",totl++);
   data_size=read(infile,&data2,3024);
//the value which was read by struct variables should be copied to buffer3 . 
   strcpy(buffer3,data2.b);  
   saddr=*(data2.s);
   (socklen_t*)saddr_size=*(data2.ssize);

   ProcessPacket(buffer3 , data_size);

   }
   while(data_size>0);

   fclose(logfile);
   close(infile);   
   printf("\n");
   printf(" Finished\n\n");
   return 0;
}

当我编译这个data_process代码时,我在行中得到错误          (socklen_t的*)saddr_size = *(data2.ssize);  警告:从不同大小的整数转换为指针[-Wint-to-pointer-cast]  错误:左值作为赋值的左操作数

我之前发过这个问题,但我得到了解决方案。因此,通过上传整个修改过的代码再次发布它。请有人帮助我。

3 个答案:

答案 0 :(得分:2)

你可以这样做 将结构更改为

struct fields{ 
        char  buffer[1024];   
        struct sockaddr saddr;
        socklen_t saddr_size;
}data; 

然后在代码中

memcpy(data.buffer,buffer,sizeof buffer);
memcpy(&data.saddr,&saddr,sizeof saddr);
memcpy(&data.saddr_size,&saddr_size,sizeof(saddr_size));
int cont = write(logfile, &data, data_size);

答案 1 :(得分:1)

代码有很多错误。要先回答你的问题,你必须使用strcpy(data.buffer,(char *)(&amp; data) - &gt; saddr);

代码中的其他错误是

  1. 您已经定义了一个结构,并且从未用于更新saddr。相反,你使用了单独的saddr变量。
  2. “data”不是您尝试使用“ - &gt;”访问的指针。结构中的“saddr”变量被声明为指针。
  3. 即使您使用该结构,您也必须为使用它之前在结构中声明的指针分配内存。否则你将面临分段错误。
  4. 未为“buffer”变量释放已分配的内存。
  5. 这种读取网络数据的方式不正确。请参阅“选择”系统调用和套接字编程中的异步读取。
  6. 如果您使用“gcc”编译器,请使用选项“-Wall -Wextra”,它将显示您的所有错误。

答案 2 :(得分:0)

通过您的代码,您无法完全清楚要将哪个变量复制到要复制值的变量。但我对你的理解很少:

strcpy(data.buffer,buffer); //i guess you need to copy data that you received from socket to the variable buffer in data(a variable of fields struct)
//i guess you need to copy received saddr to the saddr(in data variable) and as it's a pointer then you can simply assign the saddr to that pointer.
data->saddr = &saddr;
//and same assignment should work for size variable

尝试看看它是否适合你