Created
April 10, 2025 15:40
-
-
Save reitowo/67b7e3f142957644c309c2f74cafc319 to your computer and use it in GitHub Desktop.
win_af_unix_connectex.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <winsock2.h> | |
#include <windows.h> | |
#include <ws2tcpip.h> | |
#include <afunix.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <MSWSock.h> | |
#include <string> | |
#pragma comment(lib, "ws2_32.lib") | |
#pragma comment(lib, "mswsock.lib") | |
// 获取WSA扩展函数 | |
static BOOL GetExtensionFunction(SOCKET socket, GUID guid, void** target) { | |
int result; | |
DWORD bytes; | |
result = WSAIoctl(socket, | |
SIO_GET_EXTENSION_FUNCTION_POINTER, | |
&guid, | |
sizeof(guid), | |
(void*)target, | |
sizeof(*target), | |
&bytes, | |
NULL, | |
NULL); | |
if (result == SOCKET_ERROR) { | |
*target = NULL; | |
return FALSE; | |
} | |
else { | |
return TRUE; | |
} | |
} | |
// 清理资源的辅助函数 | |
void CleanupResources(SOCKET socketToClose, HANDLE iocpToClose) { | |
if (socketToClose != INVALID_SOCKET) { | |
closesocket(socketToClose); | |
} | |
if (iocpToClose != NULL && iocpToClose != INVALID_HANDLE_VALUE) { | |
CloseHandle(iocpToClose); | |
} | |
WSACleanup(); | |
} | |
int main() | |
{ | |
int err = 0; | |
char recv_buf[128] = {0}; | |
WSADATA wsa_data = {0}; | |
SOCKET uds_client_fd = INVALID_SOCKET; | |
HANDLE iocp = NULL; | |
// 初始化 Winsock | |
err = WSAStartup(MAKEWORD(2, 2), &wsa_data); | |
if (err != 0) { | |
printf("WSAStartup() error: %d\n", err); | |
return -1; | |
} | |
// 获取 ConnectEx 函数指针 | |
LPFN_CONNECTEX connectExFunc = NULL; | |
const GUID wsaid_connectex = WSAID_CONNECTEX; | |
SOCKET dummy = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | |
if (dummy == INVALID_SOCKET) { | |
printf("Failed to create dummy socket, error: %d\n", WSAGetLastError()); | |
WSACleanup(); | |
return -1; | |
} | |
if (!GetExtensionFunction(dummy, wsaid_connectex, (void**)&connectExFunc)) { | |
printf("Failed to get ConnectEx function, error: %d\n", WSAGetLastError()); | |
closesocket(dummy); | |
WSACleanup(); | |
return -1; | |
} | |
closesocket(dummy); | |
// 创建完成端口 | |
iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); | |
if (iocp == NULL) { | |
printf("CreateIoCompletionPort failed, error: %d\n", GetLastError()); | |
WSACleanup(); | |
return -1; | |
} | |
// 创建 UNIX 域套接字 | |
uds_client_fd = socket(AF_UNIX, SOCK_STREAM, IPPROTO_IP); | |
if (uds_client_fd == INVALID_SOCKET) { | |
err = WSAGetLastError(); | |
printf("Failed to create UDS socket, error: %d\n", err); | |
CleanupResources(INVALID_SOCKET, iocp); | |
return -1; | |
} | |
// 绑定套接字 | |
sockaddr_un uds_addr_bind = {0}; | |
uds_addr_bind.sun_family = AF_UNIX; | |
int ret = bind(uds_client_fd, (const struct sockaddr*)&uds_addr_bind, sizeof(uds_addr_bind)); | |
if (ret != 0) { | |
err = WSAGetLastError(); | |
printf("Failed to bind socket, error: %d\n", err); | |
CleanupResources(uds_client_fd, iocp); | |
return -1; | |
} | |
// 关联套接字到完成端口 | |
if (CreateIoCompletionPort((HANDLE)uds_client_fd, iocp, (ULONG_PTR)uds_client_fd, 0) == NULL) { | |
err = GetLastError(); | |
printf("Failed to associate socket with IOCP, error: %d\n", err); | |
CleanupResources(uds_client_fd, iocp); | |
return -1; | |
} | |
// 准备连接地址 | |
sockaddr_un uds_addr_real = {0}; | |
uds_addr_real.sun_family = AF_UNIX; | |
const char* server_path = "D:/Test"; | |
// 安全地复制路径,确保不会溢出 | |
strncpy_s(uds_addr_real.sun_path, sizeof(uds_addr_real.sun_path), server_path, _TRUNCATE); | |
// 准备重叠结构 | |
OVERLAPPED overlapped = {0}; | |
// 连接到服务器 | |
ret = connectExFunc(uds_client_fd, | |
(const struct sockaddr*)&uds_addr_real, | |
sizeof(uds_addr_real), | |
NULL, 0, NULL, &overlapped); | |
if (!ret) { | |
err = WSAGetLastError(); | |
if (err != ERROR_IO_PENDING) { | |
printf("ConnectEx failed with error: %d\n", err); | |
CleanupResources(uds_client_fd, iocp); | |
return -1; | |
} | |
printf("Connection pending...\n"); | |
// 等待连接完成 | |
DWORD bytes_transferred = 0; | |
ULONG_PTR completion_key = 0; | |
OVERLAPPED* completed_overlapped = NULL; | |
if (GetQueuedCompletionStatus(iocp, &bytes_transferred, &completion_key, | |
&completed_overlapped, 5000)) { // 5秒超时 | |
printf("Connection successful!\n"); | |
} else { | |
err = GetLastError(); | |
printf("Connection failed, error: %d\n", err); | |
CleanupResources(uds_client_fd, iocp); | |
return -1; | |
} | |
} else { | |
printf("Connection completed immediately\n"); | |
} | |
// 清理资源 | |
CleanupResources(uds_client_fd, iocp); | |
printf("Program completed successfully\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment