#include <winsock2.h>
#include <windows.h>
#include <mstcpip.h>
#pragma comment(lib,"Ws2_32.lib")
#include <iostream>
using namespace std;
//IP首部
typedef struct tIPPackHead
{
enum PROTOCOL_TYPE{
PROTOCOL_TCP = 6,
PROTOCOL_UDP = 17,
PROTOCOL_ICMP = 1,
PROTOCOL_IGMP = 2
};
inline unsigned HeadLen() const
{
//首部長度單位為4bytes。因此乘4
return (ver_hlen & 0x0F) << 2;
}
inline unsigned PackLen() const
{
return wPacketLen;
}
BYTE ver_hlen; //IP協議版本和IP首部長度。高4位為版本,低4位為首部的長度(單位為4bytes)
BYTE byTOS; //服務型別
WORD wPacketLen; //IP包總長度。包括首部,單位為byte。[Big endian]
WORD wSequence; //序號,一般每個IP包的序號遞增。[Big endian]
WORD wMarkFragPoi;
BYTE byTTL; //生存時間
BYTE byProtocolType; //協議型別,見PROTOCOL_TYPE定義
WORD wHeadCheckSum; //IP首部校驗和[Big endian]
DWORD dwIPSrc; //源地址
DWORD dwIPDes; //目的地址
} IP_PK_HEAD;
int DecodeIP(char *buf, int len);
int DecodeIP(char *buf, int len)
{
int n = len;
if( n >= sizeof(IP_PK_HEAD) )
{
IP_PK_HEAD iphead;
memcpy( &iphead, buf, sizeof(iphead) );
//以下三個為Big Endian位元組順序,轉換成主機位元組順序
iphead.wPacketLen = ntohs( iphead.wPacketLen );
iphead.wSequence = ntohs( iphead.wSequence );
iphead.wHeadCheckSum = ntohs( iphead.wHeadCheckSum );
in_addr src,dst;
src.S_un.S_addr = iphead.dwIPSrc;
dst.S_un.S_addr = iphead.dwIPDes;
char strsrc[20],strdst[20];
strcpy(strsrc, inet_ntoa(src));
strcpy( strdst , inet_ntoa(dst));
printf( "IP資料包: ver=%d,hlen=%d,protocol=%d,pklen=%d,seq=%d,src=%s,dst=%s _fcksavedurl=%s,dst=%s",
iphead.ver_hlen >> 4,
(iphead.ver_hlen & 0x0F) << 2,
iphead.byProtocolType,
iphead.wPacketLen,
iphead.wSequence,
strsrc,
strdst );
}
return 0;
}
void AutoWSACleanup()
{
::WSACleanup();
}
int main()
{
//初始化winsock庫,使用2.2版本
u_short wVersionRequested = 0x0202;
WSADATA wsaData;
if( SOCKET_ERROR == WSAStartup( wVersionRequested, &wsaData ) )
{
cout << WSAGetLastError();
return 0;
}
atexit( AutoWSACleanup );
//建立SOCKET
SOCKET h = socket( AF_INET, SOCK_RAW, IPPROTO_IP);
if( h == INVALID_SOCKET )
{
cout << WSAGetLastError();
return 0;
}
//獲取本機地址
char FAR name[128];
if( -1 == gethostname(name, sizeof(name)) )
{
closesocket( h );
cout << WSAGetLastError();
return 0;
}
struct hostent FAR * pHostent;
pHostent = gethostbyname(name);
//繫結本地地址到SOCKET控制程式碼
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr = *(in_addr*)pHostent->h_addr; //IP
addr.sin_port = 0; //埠,IP層埠可隨意填
if( SOCKET_ERROR == bind( h,(sockaddr *)&addr,sizeof(addr) ) )
{
closesocket( h );
cout << WSAGetLastError();
return 0;
}
//設定該SOCKET為接收所有流經繫結的IP的網路卡的所有資料,包括接收和傳送的資料包
//該函式在mstcpip.h裡面,詳見MSDN幫助
u_long sioarg = 1;
DWORD wt=0;
if( SOCKET_ERROR == WSAIoctl( h, SIO_RCVALL , &sioarg,sizeof(sioarg),NULL,0,&wt,NULL,NULL ) )
{
closesocket( h );
cout << WSAGetLastError();
return 0;
}
//我們只需要接收資料,因此設定為阻塞IO,使用最簡單的IO模型
u_long bioarg = 0;
if( SOCKET_ERROR == ioctlsocket( h, FIONBIO , &bioarg ) )
{
closesocket( h );
cout << WSAGetLastError();
return 0;
}
//開始接收資料
//因為前面已經設定為阻塞IO,recv在接收到資料前不會返回。
//當返回<=0時表示接收失敗,退出迴圈
//可以在另一個執行緒執行此迴圈,主執行緒closesocket可以使recv失敗而結束迴圈
char buf[102400];
int len = 0;
do
{
len = recv( h, buf, sizeof(buf),0);
if( len > 0 )
{
DecodeIP( buf, len );
}
}while( len > 0 );
closesocket( h );
return 0;
}
基於VC6.0的抓取TCP/IP資料包的C++實現
內容如下,將內容儲存為MSTCPIP.H
然後放到Microsoft Visual Studio\VC98\Include這個資料夾下面即可
// Copyright (C) Microsoft Corporation, 1996-1999
#if _MSC_VER > 1000
#pragma once
#endif
/* Argument structure for SIO_KEEPALIVE_VALS */
struct tcp_keepalive {
u_long onoff;
u_long keepalivetime;
u_long 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)
相關文章
- C++ 實現基於TCP的聊天室C++TCP
- JAVA Socket 底層是怎樣基於TCP/IP實現的???JavaTCP
- golang實現抓取IP地址的蜘蛛程式Golang
- php基於redis的list型資料結構實現ip限流操作PHPRedis資料結構
- IP和TCP抓包分析實驗TCP
- 使用Chrome快速實現資料的抓取(三)——JQueryChromejQuery
- Python基於TCP實現聊天功能PythonTCP
- TCP/IP基礎知識&Oracle的TCP/IP網路應用TCPOracle
- 使用wireshark分析TCP/IP協議中TCP包頭的格式TCP協議
- IP 資料包
- 資料包抓取工具:Debookee for macMac
- Debookee for mac(資料包抓取工具)Mac
- TCP/IP 基礎TCP
- Python抓取淘寶IP地址資料Python
- 使用代理IP抓取資料的四大優勢
- 基於vue實現的雙向資料繫結Vue
- EF架構~基於EF資料層的實現架構
- 基於OpenSSL的HTTPS通訊C++實現HTTPC++
- C++基於控制檯的迷宮實現(上)C++
- 如何使用代理IP進行資料抓取,PHP爬蟲抓取亞馬遜商品資料PHP爬蟲亞馬遜
- 無線模組透過TCP/IP協議實現與PC端的資料傳輸解析TCP協議
- Linux中使用wireshark分析tcpdump抓取的資料包LinuxTCP
- 爬蟲ip如何加入到程式碼裡實現自動化資料抓取爬蟲
- 關於資料抓取很多新人的誤區
- 基於 Flink CDC 的現代資料棧實踐
- C++基於armadillo im2col的實現C++
- 基於 electron 實現簡單易用的抓包、mock 工具Mock
- 基於python的大資料分析實戰學習筆記-pandas(資料分析包)Python大資料筆記
- 無線通訊模組透過TCP/IP協議實現與PC端的資料傳輸TCP協議
- 基於json資料格式實現的簡單資料庫——jsonDBJSON資料庫
- Python 基於 TCP 傳輸協議的網路通訊實現PythonTCP協議
- 基於 Spark 的資料分析實踐Spark
- c++實現輸出指定的格式的資料C++
- 基於C++11的資料庫連線池實現C++資料庫
- 基於資料庫、redis和zookeeper實現的分散式鎖資料庫Redis分散式
- 基於JFinal的實現echart與資料庫互動資料庫
- 基於DRBD實現資料庫高可用資料庫
- 抓取Android平臺資料包之tcpdump 工具的使用過程中出現的問題AndroidTCP