1、IP地址在程序中的表示方法并不是那么的直观,我们习惯的是十进制的点分式,例如192.168.1.1、127.0.0.1。人们一般定义一个长16的数组来存放。可是IP协议头部中的IP地址只有32位,也就是4个字节,根本无法存放,而且要求的是网络字节顺序。所以专门定义有一个结构体in_addr用来存储IP地址。
该结构的定义如下: ****************************************************** struct in_addr { union { struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b; struct { u_short s_w1,s_w2; } S_un_w; u_long S_addr; } S_un; }; ******************************************************
图方便,我直接由MSDN中复制出来了。网络字节序的IP地址就存放在S_addr中,比如我们定义了该结构体的一个变量ipaddr,使用起来就是ipaddr.S_un.S_addr。 可是实际使用时却经常为ipaddr.s_addr,在VC中的自动提示并看不到s_addr,这是因为像.S_un.S_addr敲两次太麻烦,所以windows把它定义为了宏的原因,务必记下来。 还有,为了把点分式的IP地址转换为网络字节序的s_addr,使用inet_addr函数。
2、主机字节顺序还有网络字节顺序要注意它们的区别,主机字节序是按照由高到低去读,我忘记装OFFICE了,只好用DW随便做了个表格然后QQ截图,哈哈,还挺好用~
0x123456,0x12为最高位,0x56为最低位。
而网络字节序正好与之相反,即从低地址往高地址读,那么上面的0x123456就应该是0x563412。
所以我们在程序中遇到与IP、TCP还有端口相关的地方时,记得使用honts(),hontl()这两个函数将其转换为网络字节序。对应的还有ntohs(),ntohl()函数,将网络字节序转换成主机字节序。函数原型如下:
****************************************************** u_short htons(u_short hostshort); u_long htonl(u_long hostlong); u_long ntohl(u_long netlong); u_short ntohs(u_short netshort); ******************************************************
3、一些常用的协议头部的结构体
****************************************************** typedef struct _iphdr{ //定义IP首部 unsigned char h_lenver; //4位首部+4位版本号 unsigned char tos; //8位服务类型 unsigned short total_len; //16位总长度 unsigned ident; //16位标识 unsigned short frag_and_flags; //3位标志位 unsigned char ttl; //8位生存时间 unsigned char proto; //8位协议 unsigned short checksum; //16位IP首部效验和 unsigned int sourceIP; //32位源IP地址 unsigned int destIP; //32位目的IP地址 }IP_HEADER; typedef struct _tcphdr{ //定义TCP首部 USHORT th_sport; //16位源端口 USHORT th_dport; //16位目的端口 unsigned int th_seq; //32位序列号 unsigned int th_ack; //32位确认号 unsigned char th_lenres; //4位首部长度 unsigned char th_flag; //6位标志位 USHORT th_win; //16位窗口大小 USHORT th_sum; //16位效验和 USHORT th_urp; //16位紧急数据偏移量 }TCP_HEADER;
typedef struct _udphdr{ //定义UDP首部 USHORT uh_sport; //16位源端口 USHORT uh_dport; //16位目的端口 short uh_len; //长度 USHORT uh_sum; //16位效验和 }UDP_HEADER;
typedef struct _icmphdr{ //定义ICMP首部 unsigned char type; //ICMP类型 0->回送应答 8->回送请求 unsigned char code; //代码 unsigned short checksum; //效验和 unsigned short seq; //序号 unsigned short id; //标识符 }ICMP_HEADER; ******************************************************