如何使用C程序读取来自端口的UDP数据有效负载

我正在尝试从端口6343捕获UDP数据包。在捕获它时,我还必须捕获有效负载。 我以ASCII格式获取有效载荷。 我必须阅读有效载荷的内容。 以下是我的代码:

#include //For standard things #include //malloc #include //memset #include //Provides declarations for icmp header #include //Provides declarations for udp header #include //Provides declarations for tcp header #include //Provides declarations for ip header #include #include #define PORT 6343 void print_udp_packet(unsigned char*, int); void ProcessPacket(unsigned char*, int); void PrintData (unsigned char* , int); int sockt; int i,j; struct sockaddr_in source,dest; int main() { int saddr_size,data_size; struct sockaddr_in saddr; struct sockaddr_in daddr; //struct in_addr in; unsigned char *buffer = (unsigned char *)malloc(65536); // Its Big ! Malloc allocates a block of size bytes of memory,returning a pointer to the begining of the block struct udphdr *udph = (struct udphdr*)(buffer + sizeof(struct iphdr)); struct iphdr *iph = (struct iphdr *)buffer; memset(&source,0,sizeof(source)); source.sin_addr.s_addr = iph ->saddr; memset(&dest,0,sizeof(dest)); dest.sin_addr.s_addr = iph->daddr; unsigned short iphdrlen = iph->ihl*4; printf("Starting...\n"); //Create a socket sockt = socket(AF_INET ,SOCK_DGRAM ,0); if(sockt < 0) { printf("Socket Error\n"); return 1; } memset((char *)&daddr,0,sizeof(daddr)); //prepare the sockaddr_in structure daddr.sin_family = AF_INET; daddr.sin_addr.s_addr = htonl(INADDR_ANY); daddr.sin_port = htons(PORT); //Bind if(bind(sockt,(struct sockaddr *)&daddr, sizeof(daddr))<0) { printf("bind failed"); return 1; } printf("bind done"); while(1) { saddr_size = sizeof saddr; printf("waiting for data..."); //Receive a packet data_size = recvfrom(sockt , buffer ,65536 , 0 , (struct sockaddr*) &saddr , (socklen_t*)&saddr_size); if(data_size source), ntohs(udph->dest), ntohs(data_size), (unsigned int)iph->protocol, ntohs(iph->tot_len)); printf("Source IP : %s\n",inet_ntoa(saddr.sin_addr)); printf("Destination IP : %s\n",inet_ntoa(daddr.sin_addr)); ProcessPacket(buffer,data_size); } close(sockt); printf("Finished"); return 0; } void ProcessPacket(unsigned char* buffer, int size) { print_udp_packet(buffer ,size); } void print_udp_packet(unsigned char *buffer , int size) { unsigned short iphdrlen; struct iphdr *iph = (struct iphdr *)buffer; iphdrlen = iph->ihl*4; struct udphdr *udph = (struct udphdr*)(buffer + iphdrlen); printf("Data Payload\n"); PrintData(buffer + iphdrlen + sizeof udph ,( size - sizeof udph - iph->ihl * 4 )); printf("\n###########################################################"); } void PrintData (unsigned char* data , int size) { for(i=0 ; i < size ; i++) { if( i!=0 && i%16==0) //if one line of hex printing is complete... { printf(" "); for(j=i-16 ; j=32 && data[j]<=128) printf("%c",(unsigned char)data[j]); //if its a number or alphabet else printf("."); //otherwise print a dot } printf("\n"); } if(i%16==0) printf(" "); printf(" %02X",(unsigned int)data[i]); if( i==size-1) //print the last spaces { for(j=0;j<15-i%16;j++) printf(" "); //extra spaces printf(" "); for(j=ii%16 ; j=32 && data[j]<=128) printf("%c",(unsigned char)data[j]); else printf("."); } printf("\n"); } } } 

我收到的输出如下:

 Source Port : 55784 , Destination Port : 59568, UDP Length : 5122,Protocol : 188, total length : 5122 Source IP : 147.188.195.6 Destination IP : 0.0.0.0 Data Payload 93 BC C0 06 00 00 00 00 00 1F 39 D4 D9 E8 E8 B0 ..........9..... 00 00 00 03 00 00 00 01 00 00 00 9C 00 B1 C9 4E ...............N 00 00 00 1D 00 00 01 00 78 F9 F5 6B 00 10 67 8F ........x..k..g. 00 00 00 1D 00 00 00 28 00 00 00 02 00 00 00 01 .......(........ 00 00 00 5C 00 00 00 01 00 00 00 4E 00 00 00 04 ...\.......N.... 00 00 00 4C F0 92 1C 48 C2 00 00 0E 0C 30 C7 C7 ...L...H.....0.. 08 00 45 00 00 3C 28 4D 40 00 25 06 1C 7E 4C 5C ..E......?. 38 9F 93 BC C0 04 C2 53 70 05 00 35 BE FE 00 2A 8......Sp..5...* 28 53 82 D8 81 05 00 01 00 00 00 00 00 00 03 77 (S.............w 77 77 06 67 6F 6F 67 6C 65 02 63 6F 02 75 6B 00 ww.google.co.uk. 00 01 00 01 00 00 03 E9 00 00 00 10 FF FF FF FF ................ 00 00 00 00 00 00 00 03 FF FF FF FF ............ 

我很困惑如何将这些数据变成可读forms以了解有效载荷的内容?

首先,您打印的端口号,协议和数据长度不正确。 正如我在回答您之前的问题时提到的那样 ,IP和UDP标头不包含在由recvfrom填充的缓冲区中。 源端口和目标端口分别位于saddr.sin_portdaddr.sin_port (确保在打印前在这些字段上调用ntohs ),UDP有效负载长度是recvfrom的返回值,即data_size

至于数据有效负载的格式,您需要准确了解您收到的数据的格式。 在此基础上,您可以提取相关字段并以可读格式打印。 对于初学者,您可以从main调用PrintData而不是ProcessPacket ,因为您不需要担心IP和UDP标头。