#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <stdlib.h>
#include <Windows.h>
#include <string.h>
#pragma comment(lib,"Ws2_32.lib")
#define SOURCE_PORT 7234
#define MAX_RECEIVEBYTE 255
#define MAX_ADDR_LEN 32
#define SIO_RCVALL (IOC_IN|IOC_VENDOR|1)//定義網卡為混雜模式
typedef struct ip_hdr//定義IP首部
{
unsigned char h_verlen;//4位首部長度,4位IP版本號
unsigned char tos;//8位服務型別TOS
unsigned short tatal_len;//16位總長度
unsigned short ident;//16位標示
unsigned short frag_and_flags;//偏移量和3位標志位
unsigned char ttl;//8位生存時間TTL
unsigned char proto;//8位協議(TCP,UDP或其他)
unsigned short checksum;//16位IP首部檢驗和
unsigned int sourceIP;//32位源IP地址
unsigned int destIP;//32位目的IP地址
}IPHEADER;
typedef struct udp_hdr//定義UDP首部
{
unsigned short sport;//16位源埠
unsigned short dport;//16位目的埠
unsigned short len;//UDP 長度
unsigned short cksum;//檢查和
}UDPHEADER;
int main(int argc, char **argv)
{
//try{
SOCKET sock;
WSADATA wsd;
char recvBuf[65535] = { 0 };
DWORD dwBytesRet;
int pCount = 0;
unsigned int optval = 1;
unsigned char* dataudp = NULL;
int lenudp,lenip;
WSAStartup(MAKEWORD(2, 1), &wsd);
if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) == SOCKET_ERROR)//創建一個原始套接字
{
exit(0);
}
char FAR name[MAXBYTE];
gethostname(name, MAXBYTE);
struct hostent FAR* pHostent;
pHostent = (struct hostent*)malloc(sizeof(struct hostent));
pHostent = gethostbyname(name);
SOCKADDR_IN sa;
sa.sin_family = AF_INET;
sa.sin_port = htons(1);//原始套接字沒有埠的概念,所以這個值隨便設定
memcpy(&sa.sin_addr,pHostent->h_addr_list[0],pHostent->h_length);//設定本機地址
bind(sock, (SOCKADDR*)&sa, sizeof(sa));//系結
if (WSAGetLastError() == 10013)
{
exit(0);
}
//設定網卡為混雜模式,也叫泛聽模式。可以偵聽經過的所有的包。
WSAIoctl(sock, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwBytesRet,NULL,NULL);
UDPHEADER * pUdpheader;//UDP頭結構體指標
IPHEADER * pIpheader;//IP頭結構體指標
char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN];//源IP和目的IP
SOCKADDR_IN saSource, saDest;//源地址結構體,目的地址結構體
//設定各種頭指標
pIpheader = (IPHEADER*)recvBuf;
pUdpheader = (UDPHEADER*)(recvBuf + sizeof(IPHEADER));
//int iIphLen = sizeof(unsigned long)*(pIpheader->h_verlen & 0x0f);
while (1)
{
memset(recvBuf, 0, sizeof(recvBuf));//清慷訓沖區
recv(sock, recvBuf, sizeof(recvBuf), 0);//接收包
//獲得源地址和目的地址
saSource.sin_addr.s_addr = pIpheader->sourceIP;
strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN);
saDest.sin_addr.s_addr = pIpheader->destIP;
strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN);
//計算各種包的長度(只有判斷是否是該包后才有意義,先計算出來)
lenudp = ntohs(pIpheader->tatal_len) - (sizeof(IPHEADER) + sizeof(UDPHEADER));
//判斷是否是UDP包
if (pIpheader->proto == IPPROTO_UDP&&lenudp !=0)
{
pCount++;//計數加一
dataudp = (unsigned char *)recvBuf + sizeof(IPHEADER) + sizeof(UDPHEADER);
system("cls");
printf("\n#################資料包[%i]=%d位元組資料#############", pCount,lenudp);
printf("\n**********IP協議頭部***********");
printf("\n源IP:%s", szSourceIP);
printf("\n目的IP:%s", szDestIP);
printf("\n**********UDP協議頭部***********");
printf("\n源埠:%i", ntohs(pUdpheader->sport));
printf("\n目的埠:%i", ntohs(pUdpheader->dport));
if(ntohs(pUdpheader->dport)==5169){
printf("\n資料:\n");
for (int i = 0; i < 189; i++) //列印出前100個位元組的十六進制資料
{
printf( "%x",dataudp[i]); //
}
}
}
}//while
}
請教:
代碼可以正常截取本機發出的UDP資料
問題 當運行程序中,禁用網卡,IP地址變成127.0.0.1 的時候就卡在while回圈里
請問一下如何判斷錯誤 try 無效
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/87700.html
標籤:C++ 語言
上一篇:C++全域鍵盤監聽
