[原创]匆忙写的一个完成端口DEMO
#define WIN32_LEAN_AND_MEAN
#define mm_alloc(x) malloc(x)
#define mm_free(x) free(x)
#pragma comment(lib, "ws2_32.lib")
#include <windows.h>
#include <winsock2.h>
#include <mswsock.h>
enum iocp_op_type{
OP_CONNECT,
OP_SEND,
OP_RECV,
OP_MAX
};
typedef struct per_io_sock{
DWORD io_op;
WSABUF io_buf;
SOCKET sock;
} PER_IO_SOCK, *PPER_IO_SOCK;
typedef struct iocp_socks{
HANDLE port;
ULONG is_exit;
LPFN_CONNECTEX connectex;
int (*on_sock_complet)(PPER_IO_SOCK io_sock);
} IOCP_SOCKS, *PIOCP_SOCKS;
DWORD WINAPI iocp_query_thread(PIOCP_SOCKS iocp)
{
DWORD bytes;
OVERLAPPED ol;
PPER_IO_SOCK io_sock;
BYTE buf[1024] = {0};
while (!iocp->is_exit){
BOOL bResult = GetQueuedCompletionStatus (
iocp->port,
&bytes,
(PULONG_PTR)&io_sock,
&ol,
INFINITE);
if (!bResult)
continue;
printf("%x %p \n", io_sock->io_op, io_sock);
if (io_sock->io_op == OP_CONNECT){
iocp_send(iocp, io_sock, "GET / HTTP/1.1\r\n\r\n", 18);
} else if (io_sock->io_op == OP_SEND){
printf("SEND %d DONE\n", bytes);
iocp_recv(iocp, io_sock, buf, sizeof(buf));
} else if (io_sock->io_op == OP_RECV){
printf("RECV %d DONE\n%s", bytes, buf);
}
if (iocp->on_sock_complet){
iocp->on_sock_complet(io_sock);
}
}
return 0;
}
int init_iocp(PIOCP_SOCKS iocp)
{
WSADATA wsd;
GUID GuidConnectEx = WSAID_CONNECTEX;
SOCKET sock;
DWORD dwBytes = 0;
WSAStartup(MAKEWORD(2, 2), &wsd);
sock = WSASocket (AF_INET,
SOCK_STREAM,
IPPROTO_TCP,
NULL,
NULL,
WSA_FLAG_OVERLAPPED);
if (SOCKET_ERROR == WSAIoctl (sock,
SIO_GET_EXTENSION_FUNCTION_POINTER ,
&GuidConnectEx,
sizeof (GuidConnectEx ),
&iocp->connectex,
sizeof (iocp->connectex),
&dwBytes,
0,
0))
return -1;
iocp->port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
iocp->is_exit = 0;
CloseHandle(CreateThread(NULL, 0, iocp_query_thread, iocp, 0, NULL));
closesocket(sock);
return 0;
}
HANDLE iocp_accept(PIOCP_SOCKS iocp)
{
}
int iocp_recv(PIOCP_SOCKS iocp, PPER_IO_SOCK io_sock, LPBYTE buf, DWORD count)
{
OVERLAPPED ol = {0};
DWORD flags = 0;
int ret;
io_sock->io_op = OP_RECV;
io_sock->io_buf.buf = buf;
io_sock->io_buf.len = count;
ret = WSARecv(
io_sock->sock,
&io_sock->io_buf,
1,
NULL,
&flags,
&ol,
NULL);
return 0;
}
int iocp_send(PIOCP_SOCKS iocp, PPER_IO_SOCK io_sock, LPBYTE buf, DWORD count)
{
OVERLAPPED ol = {0};
int ret;
io_sock->io_op = OP_SEND;
io_sock->io_buf.buf = buf;
io_sock->io_buf.len = count;
ret = WSASend (
io_sock->sock,
&io_sock->io_buf,
1,
&count,
0,
&ol,
0);
return ret;
}
HANDLE iocp_connect(PIOCP_SOCKS iocp, ULONG ip, WORD port)
{
SOCKET sock;
struct sockaddr_in sock_addr = {0};
PPER_IO_SOCK io_sock;
DWORD dwBytesSent = 0;
BOOL bResult;
OVERLAPPED ol = {0};
sock = WSASocket (AF_INET,
SOCK_STREAM,
IPPROTO_TCP,
NULL,
NULL,
WSA_FLAG_OVERLAPPED);
sock_addr.sin_family = AF_INET;
bind(sock, (struct sockaddr *)(&sock_addr), sizeof(sock_addr));
io_sock = mm_alloc(sizeof(PER_IO_SOCK));
memset(io_sock, 0, sizeof(PER_IO_SOCK));
io_sock->sock = sock;
io_sock->io_op = OP_CONNECT;
CreateIoCompletionPort (sock, iocp->port, (ULONG_PTR)io_sock, 0);
sock_addr.sin_addr.s_addr = ip;
sock_addr.sin_port = htons(port);
bResult = iocp->connectex (sock,
(struct sockaddr *)&sock_addr,
sizeof(sock_addr),
NULL,
0,
&dwBytesSent,
&ol);
if (!bResult){
printf("%d %d\n", ERROR_IO_PENDING, WSAGetLastError ());
}
return io_sock;
}
int main(int argc, char** argv)
{
IOCP_SOCKS iocp = {0};
init_iocp(&iocp);
iocp_connect(&iocp, inet_addr("172.16.16.99"), 80);
getchar();
return 0;
}
[ATTACH]79016[/ATTACH]
注意:上传附件及图片大小不得大于30M。
⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。