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

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

接收和处理数据包时出现问题,因为我曾经在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) { 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]错误:作为赋值的左操作数需要左值

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

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

您的代码中的其他错误是,

  1. 您已经定义了一个结构,从未用于更新saddr。 相反,你使用了单独的saddr变量。
  2. “data”不是您尝试使用“ – >”访问的指针。 结构内部的“saddr”变量被声明为指针。
  3. 即使您使用该结构,您也必须为使用它之前在结构中声明的指针分配内存。 否则你将面临分段错误。
  4. 为“缓冲区”变量释放已分配的内存。
  5. 这种读取网络数据的方式不正确。 请参阅套接字编程中的“select”系统调用和异步读取。

如果您使用“gcc”编译器,请使用选项“-Wall -Wextra”,它将显示您的所有错误。

你可以像这样改变结构

 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); 

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

 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 

试试看它是否适合你