注:如果用的是VS打开的话,可能会提示缺少msvc**.dll文件,可以用360电脑救援搜索该文件,修复即可。
main.cpp:
#include <stdio.h>
#include"mstcpip.h"
#include<ws2tcpip.h>
#include<iostream>
#include<string>
#include <WINSOCK2.H>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
typedef struct _IP_HEADER //定义IP头
{
union
{
BYTE Version; //版本(前4位)
BYTE HdrLen; //报头长度(后4位),IP头的双字长度
};
BYTE ServiceType; //服务类型
WORD TotalLen; //IP信包字节总长度
WORD ID; //IP信包标识号
// WORD DF;
// WORD MF;
union
{
WORD Flags; //标志位(前3位:0,DF,MF)
WORD FragOff; //分段偏移(后13位,以8字节为单位)
};
BYTE TimeToLive; //生命期TTL值
BYTE Protocol; //高层协议号(TCP:6,UDP:17,ICMP:1,IGMP:2)
WORD HdrChksum; //头校验和
DWORD SrcAddr; //源IP地址
DWORD DstAddr; //目的IP地址
BYTE Options; //选项
} IP_HEADER;
int main()
{
WSADATA wsaData; //指向WinSocket信息结构的指针
if(WSAStartup(MAKEWORD( 1, 1 ), &wsaData )!=0)//进行WinSocket的初始化
{
printf("Can't initiates windows socket!Program stop.\n");//初始化失败返回-1
return -1;
}
SOCKET sock;
sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0, WSA_FLAG_OVERLAPPED);
BOOL flag=true;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char*)&flag,sizeof(flag));
setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(CHAR*)&flag,sizeof(flag));
/*获取主机名*/
char hostName[128];
gethostname(hostName,100);
/*获取本地IP地址*/
hostent * pHostIP;
pHostIP = gethostbyname(hostName);
/*填充SOCKADDR_IN结构的内容*/
sockaddr_in addr_in;
addr_in.sin_addr = *(in_addr *)pHostIP->h_addr_list[0];
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(6000);
// 绑定套接字,将sock绑定到本机网卡上
bind(sock,(PSOCKADDR)&addr_in,sizeof(addr_in));
DWORD dwBufferLen[10];
DWORD dwBufferInLen = 1;
DWORD dwBytesReturned = 0;
WSAIoctl(sock, SIO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen),
&dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL);
#define BUFFER_SIZE 65535
char buffer[BUFFER_SIZE]; //设置缓冲区
//int err=0;
printf("IP包内容:\n");
for(int m=0; m<2; m++) //准备收2个包
{
int n= recv(sock,buffer,BUFFER_SIZE,0); //接收一个数据包 ,n为数据长度
if(WSAGetLastError()==SOCKET_ERROR)
{
if(WSAGetLastError()==WSAEWOULDBLOCK)
continue; //如果错误为阻塞那么将继续接受
break;
}
/*然后是处理显示接收的IP包中的字节*/
printf("(%d) ", m + 1);
for(int i = 0; i < n; i++)
{
printf("%02x ",(unsigned char)buffer[i]);
}
printf("\n");
/*然后是解析接收的IP包*/
IP_HEADER ip=*(IP_HEADER*)buffer;
//IP包的解析
//通过IP_HEADER解析IP头各个字段的代码:
/*获取版本字段*/
printf("IP包解析结果:\n");
int version;
version=ip.Version>>4; //取前四位
printf("IPVersion:IPV%d\n",version);
/*获取头部长度字段*/
int length;
length=ip.HdrLen & 0x0f;
printf("头部长度:%d字节\n",length*4);
//printf("%d",ip.HdrLen);
/*获取服务类型字段中的优先级子域*/
ip.ServiceType>>5;
/*获取服务类型字段中的TOS子域*/
(ip.ServiceType>>1)&0x0f;
/*获取总长度字段*/
ip.TotalLen;
printf("总长度:%d字节\n",ip.TotalLen);
/*获取标识字段*/
ip.ID;
/*解析标志字段*/
//ip.DF = (ip.Flags>>14) & 0x01;
//ip.MF = (ip.Flags>>13) & 0x01;
/*获取分段偏移字段*/
ip.FragOff & 0x1fff;
/*获取生存时间字段*/
ip.TimeToLive;
printf("生存时间:%d\n",ip.TimeToLive);
/*获取协议字段*/
printf("上层协议:");
if(ip.Protocol==17)
printf("UDP\n");
else if(ip.Protocol==6)
printf("TCP\n");
else if(ip.Protocol==1)
printf("ICMP\n");
else if(ip.Protocol==2)
printf("IGMP\n");
else
printf("ERROR");
/*获取头校验和字段*/
ip.HdrChksum;
/*解析源IP地址字段*/
char *srcip,*desip;
srcip=inet_ntoa(*(in_addr*)&ip.SrcAddr);
printf("源地址:%s\n",srcip);
//printf("%d%d%d%d",ip.SrcAddr);
/*解析目的IP地址字段*/
desip=inet_ntoa(*(in_addr*)&ip.DstAddr);
printf("目的地址:%s\n",desip);
//printf("%d%d%d%d",ip.SrcAddr);
}
closesocket(sock);
WSACleanup();
}
mstcpip.h:
#ifndef _MSTCPIP_INC
#define _MSTCPIP_INC
// Copyright (C) Microsoft Corporation, 1996-1999
#if _MSC_VER > 1000
#pragma once
#endif
/* Argument structure for SIO_KEEPALIVE_VALS */
//#include <stdio.h>
#include<string>
//#include<iostream>
//#include <nldef.h>
//#include <winapifamily.h>
struct tcp_keepalive {
_ULonglong onoff;
_ULonglong keepalivetime;
_ULonglong keepaliveinterval;
};
// New WSAIoctl Options
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
#define SIO_RCVALL_MCAST _WSAIOW(IOC_VENDOR,2)
#define SIO_RCVALL_IGMPMCAST _WSAIOW(IOC_VENDOR,3)
#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
#define SIO_ABSORB_RTRALERT _WSAIOW(IOC_VENDOR,5)
#define SIO_UCAST_IF _WSAIOW(IOC_VENDOR,6)
#define SIO_LIMIT_BROADCASTS _WSAIOW(IOC_VENDOR,7)
#define SIO_INDEX_BIND _WSAIOW(IOC_VENDOR,8)
#define SIO_INDEX_MCASTIF _WSAIOW(IOC_VENDOR,9)
#define SIO_INDEX_ADD_MCAST _WSAIOW(IOC_VENDOR,10)
#define SIO_INDEX_DEL_MCAST _WSAIOW(IOC_VENDOR,11)
#endif