add:基础win示例。

This commit is contained in:
taynpg 2024-08-21 02:25:46 +08:00
parent 52500ecfd0
commit 78b204ac00
3 changed files with 158 additions and 1 deletions

View File

@ -136,6 +136,8 @@
"concepts": "cpp", "concepts": "cpp",
"coroutine": "cpp", "coroutine": "cpp",
"format": "cpp", "format": "cpp",
"stop_token": "cpp" "stop_token": "cpp",
"span": "cpp",
"unordered_set": "cpp"
} }
} }

12
CMakeLists.txt Normal file
View File

@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.16)
project(SockGrab)
if (MSVC)
add_compile_options(/source-charset:utf-8)
add_compile_options(-D_CRT_SECURE_NO_WARNINGS)
endif()
add_executable(SockGrab win/main.cpp)
target_link_libraries(SockGrab PRIVATE ws2_32)

143
win/main.cpp Normal file
View File

@ -0,0 +1,143 @@
#include <WinSock2.h>
#include <mstcpip.h>
#include <ws2tcpip.h> // For gethostname()
#include <iostream>
#include <string>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cout << "Failed to initialize Winsock." << std::endl;
return -1;
}
// 创建原始套接字
auto sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (sock == INVALID_SOCKET) {
std::cout << "Invalid socket. Error code: " << WSAGetLastError() << std::endl;
WSACleanup();
return -1;
}
// 获取本地主机名
char name[128]{};
if (gethostname(name, sizeof(name)) == SOCKET_ERROR) {
std::cout << "Error getting hostname. Error code: " << WSAGetLastError() << std::endl;
closesocket(sock);
WSACleanup();
return -1;
}
// 解析本地主机名
struct hostent* pHostent = gethostbyname(name);
if (!pHostent) {
std::cout << "Error resolving host. Error code: " << WSAGetLastError() << std::endl;
closesocket(sock);
WSACleanup();
return -1;
}
// 绑定本地地址到SOCKET句柄
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr = *(in_addr*)pHostent->h_addr_list[0];
addr.sin_port = 0; // 0表示让系统选择端口
if (bind(sock, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) {
std::cout << "Bind failed. Error code: " << WSAGetLastError() << std::endl;
closesocket(sock);
WSACleanup();
return -1;
}
// 设置SOCKET为接收所有流经绑定的IP的网卡的所有数据,包括接收和发送的数据包
u_long sioarg = 1;
DWORD wt = 0;
if (WSAIoctl(sock, SIO_RCVALL, &sioarg, sizeof(sioarg), NULL, 0, &wt, NULL, NULL) == SOCKET_ERROR) {
std::cout << "WSAIoctl failed. Error code: " << WSAGetLastError() << std::endl;
closesocket(sock);
WSACleanup();
return -1;
}
// 创建事件对象
HANDLE g_event = CreateEvent(NULL, TRUE, FALSE, NULL);
if (g_event == NULL) {
std::cout << "CreateEvent failed. Error code: " << GetLastError() << std::endl;
closesocket(sock);
WSACleanup();
return -1;
}
// 使用事件选择
if (WSAEventSelect(sock, g_event, FD_READ | FD_CLOSE) == SOCKET_ERROR) {
std::cout << "WSAEventSelect failed. Error code: " << WSAGetLastError() << std::endl;
CloseHandle(g_event);
closesocket(sock);
WSACleanup();
return -1;
}
// 接收数据并打印
char buffer[65536]; // 缓冲区大小
while (true) {
// 等待事件触发
DWORD wait_result = WSAWaitForMultipleEvents(1, &g_event, TRUE, WSA_INFINITE, TRUE);
if (wait_result == WSA_WAIT_FAILED) {
std::cout << "WSAWaitForMultipleEvents failed. Error code: " << WSAGetLastError() << std::endl;
break;
}
// 清除事件
if (!ResetEvent(g_event)) {
std::cout << "ResetEvent failed. Error code: " << GetLastError() << std::endl;
break;
}
// 处理接收到的数据
sockaddr_in source_addr;
int addrlen = sizeof(source_addr);
int bytes_received = recvfrom(sock, buffer, sizeof(buffer), 0, (sockaddr*)&source_addr, &addrlen);
if (bytes_received == SOCKET_ERROR) {
int error_code = WSAGetLastError();
if (error_code != WSAEWOULDBLOCK) {
std::cout << "recvfrom error: " << error_code << std::endl;
break;
}
// 如果是非阻塞模式的超时错误,继续循环
continue;
}
// 打印接收到的数据
std::cout << "Received packet of size: " << bytes_received << " bytes" << std::endl;
// 打印远端 IP 地址和端口
char ip_address[INET_ADDRSTRLEN];
if (inet_ntop(AF_INET, &source_addr.sin_addr, ip_address, sizeof(ip_address)) != NULL) {
std::cout << "Source IP: " << ip_address << std::endl;
std::cout << "Source Port: " << ntohs(source_addr.sin_port) << std::endl;
} else {
std::cout << "Error converting IP address. Error code: " << WSAGetLastError() << std::endl;
}
// 打印数据内容
for (int i = 0; i < bytes_received; ++i) {
std::cout << std::hex << (unsigned int)(unsigned char)buffer[i] << " ";
if ((i + 1) % 16 == 0) std::cout << std::endl;
}
std::cout << std::endl;
}
// 清理资源
CloseHandle(g_event);
closesocket(sock);
WSACleanup();
return 0;
}