另外,这里也不需要setsockopt
#include<iostream>
#include<winsock2.h>
#include<ws2tcpip.h>
#pragma comment(lib,"ws2_32")
#define IO_RCVALL _WSAIOW(IOC_VENDOR,1)
typedef struct IP_HEAD
{
union
{
unsigned char Version
unsigned char HeadLen
}
unsigned char ServiceType
unsigned short TotalLen
unsigned short Identifier
union
{
unsigned short Flags
unsigned short FragOffset
}
unsigned char TimeToLive
unsigned char Protocol
unsigned short HeadChecksum
unsigned int SourceAddr
unsigned int DestinAddr
unsigned char Options
}ip_head
void main(int argc,char *argv[])
{
using namespace std
if(argc!=2)
{
cout<<endl<<"请以下格式输入命令行:PackParse packet_sum"<<endl
return
}
WSADATA WSAData
if(WSAStartup(MAKEWORD(2,2), &WSAData)!=0)
{
cout<<endl<<"WSASTartup初始化失败"<<endl
return
}
SOCKET sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP)
if(sock==INVALID_SOCKET)
{
cout<<endl<<"创建Socket失败!"<<endl
goto exit_clean
}
BOOL flag=TRUE
if(setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *) &flag,sizeof(flag))==SOCKET_ERROR)
{
cout<<endl<<"setsockopt *** 作失败:"<<WSAGetLastError()<<endl
goto exit_clean
}
char hostName[128]
if(gethostname(hostName,100)==SOCKET_ERROR)
{
cout<<endl<<"gethostname *** 作失败:"<<WSAGetLastError()<<endl
goto exit_clean
}
hostent *pHostIP
if((pHostIP=gethostbyname(hostName))==NULL)
{
cout<<endl<<"gethostbyname *** 作失败:"<<WSAGetLastError()<<endl
goto exit_clean
}
sockaddr_in host_addr
host_addr.sin_family=AF_INET
host_addr.sin_port=htons(6000)
host_addr.sin_addr=*(in_addr *)pHostIP->h_addr_list[0]
if(bind(sock,(PSOCKADDR)&host_addr,sizeof(host_addr))==SOCKET_ERROR)
{
cout<<endl<<"bind *** 作失败:"<<WSAGetLastError()<<endl
goto exit_clean
}
DWORD dwBufferLen[10]
DWORD dwBufferInLen=1
DWORD dwBytesReturned=0
if(WSAIoctl(sock , IO_RCVALL ,&dwBufferInLen , sizeof(dwBufferInLen) , &dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL)==SOCKET_ERROR)
{
cout<<endl<<"WSAIoctl *** 作失败:"<<WSAGetLastError()<<endl
goto exit_clean
}
cout<<endl<<"开始解析IP包:"<<endl
char buffer[65535]
int packsum=atoi(argv[1])
for(int i=0i<packsumi++)
{
if(recv(sock,buffer,65535,0)>0)
{
ip_head ip=*(ip_head *)buffer
cout<<"-----------------------"<<endl
cout<<"版本:"<<(ip.Version>>4)<<endl
cout<<"头部长度:"<<((ip.HeadLen &0x0f)*4)<<endl
cout<<"服务类型:Priority"<<(ip.ServiceType>>5)<<", Service"<<((ip.ServiceType>>1)&0x0f)<<endl
cout<<"总长度:"<<ip.TotalLen<<endl
cout<<"标识符:"<<ip.Identifier<<endl
cout<<"标志位:"<<((ip.Flags>>15)&0x01)<<",DF= "<<((ip.Flags>>14)&0x01)<<",Mf="<<((ip.Flags>>13)&0x01)<<endl
cout<<"片偏移:"<<(ip.FragOffset&0x1fff)<<endl
cout<<"生存周期:"<<(int)ip.TimeToLive<<endl
cout<<"协议:Protocol"<<(int)ip.Protocol<<endl
cout<<"头部校验和:"<<ip.HeadChecksum<<endl
cout<<"原地址:"<<inet_ntoa(*(in_addr *)&ip.SourceAddr)<<endl
cout<<"目的IP地址:"<<inet_ntoa(*(in_addr *)&ip.DestinAddr)<<endl
}
}
exit_clean:
closesocket(sock)
WSACleanup()
}
首先要看version是引用类型,其肯定是返回参数。b为Byte类型,其实就是二进制类型其样式为10011101,一共八个bit。b>>4就是移位运算,10011101 >>4 = 00001001(举例)
很明显,version版本存放在b的高4位中。
result = (b&0x0f)*4这个很明显是为了提取b的低四位数据,因为0x0f = (0000 1111)(B),然后乘以*4,就是左移2位,我擦楼主,你好好看看谭浩强的书吧!1 <<2 = 2^2 = 4
swith(b>>5)右移5位,和上面一样,如果是 1001 1101 >>5 = 0000 0100
后面的我就不说了,其实如果你理解前面的,后面的就都懂了。
楼猪,建议你看看谭浩强的书,位运算章节,不是很难。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)