Skip to content

Instantly share code, notes, and snippets.

@reitowo
Created April 10, 2025 15:40
Show Gist options
  • Save reitowo/67b7e3f142957644c309c2f74cafc319 to your computer and use it in GitHub Desktop.
Save reitowo/67b7e3f142957644c309c2f74cafc319 to your computer and use it in GitHub Desktop.
win_af_unix_connectex.cpp
#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