如何获取收到的UDP数据包的长度?使用wireshark我可以看到正确的数据报长度.如何在我的简单udp服务器程序中打印此值?我正在接收二进制数据(不可打印的ascii字符作为数据)所以我不能使用strlen(buf),它会抛出不正确的长度.
if (ret=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_other, &slen)==-1){ error = ioctl(s, FIONREAD, &value); printf(" from ioctl UDP packet length is : %d error is : %d\n", value, error); }
udp数据包长度始终为上述代码中的"0".任何意见?
我也尝试过如下
if (ret=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_other, &slen)!=-1){ unsigned short iphdrlen; struct iphdr* iph = (struct iphdr*)buf; iphdrlen =iph->ihl*4; printf("IP version :%d\n", ((unsigned int)((iph->version)))); printf("protocol .. %d\n", ((unsigned int)(iph->protocol))); printf("total len .. %d\n", (ntohs(iph->tot_len))); }
上面的代码总是从ip header返回错误的值?任何意见?
原始C文件包含在此处.
#include "udp_common.h" int main(void) { struct sockaddr_in si_me, si_other; int s, i, slen=sizeof(si_other); unsigned char buf[BUFLEN]; int noofbytes=0; int ret=0,error,value; memset(buf, 0, 512); if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) diep("socket"); memset((char *) &si_me, 0, sizeof(si_me)); si_me.sin_family = AF_INET; si_me.sin_port = htons(PORT); si_me.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(s, (struct sockaddr *)&si_me, sizeof(si_me))==-1) diep("bind"); for (i=0; ; i++) //for (i=0; iihl*4; printf("IP version :%d\n", ((unsigned int)((iph->version)))); printf("protocol .. %d\n", ((unsigned int)(iph->protocol))); printf("total len .. %d\n", (ntohs(iph->tot_len))); error = ioctl(s, FIONREAD, &value); printf(" from ioctl UDP packet length is : %d error is : %d\n", value, error); printf(" Return code from recvfrom is : %d\n", ret); printf("Received packet from %s:%d\nData: %s\n\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf); int j=0; for ( j = 0; j <20; j++) { char x = buf[j]; short int i; for (i=1;i<9;i++) { ((x | (1<<8-i)) == x)?printf("1"):printf("0"); } printf(" "); } printf("\n"); } close(s); return 0; }
我收到的输出如下:
source port is : 4232 16 IP version :1 protocol .. 65 total len .. 4096 from ioctl UDP packet length is : 0 error is : 0 Return code from recvfrom is : 0 Received packet from 127.0.0.1:4232 Data: 00010000 00000001 00010000 00000000 11110001 00010001 00010001 00100100 01000100 01000001 00010001 00100100 01000100 01000000 00000000 00010000 00000000 00010000 10100000 10100000
上述解密数据与我发送的数据相匹配.
你是如何创建套接字的?它是原始套接字(SOCK_RAW)还是dgram套接字(SOCK_DGRAM)?在第二种情况下,您将不会获得ip/udp标头,只有有效负载.
顺便说一下,数据包长度是函数recvfrom的返回值 - 在您的情况下,是"ret"变量.检查recvfrom手册页.