#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib ")
#define READ 0
#define WRITE 1
#define BUFFSIZE 4000
char *szTitle = "Test";
char *szWindowClass = "Test";
HINSTANCE hInst;
HANDLE hIocp;
SOCKET sListen;
SOCKADDR_IN InternetAddr;
HWND hWnd, hBtn_Start, hBtn_Stop, hBtn_Test, hEdit, hCombox;
BOOL bRun;
//typedef struct _PER_IO_OPERATION_DATA
//{
// OVERLAPPED Overlapped; //Overlapped结构
// WSABUF DataBuff; //用于存放接收数据
// char Buff[24];
// unsigned long recvBytes; //存储接收到的字节数
// SOCKADDR_IN remoteAddr; //存储数据来源IP地址
// int remoteAddrLen; //存储数据来源IP地址长度
//}PER_IO_OPERATION_DATA, *LPPER_IO_OPERATION_DATA;
typedef struct _PER_IO_OPERATION_DATA
{
OVERLAPPED Overlapped; //Overlapped结构
WSABUF DataBuff; //用于存放接收数据
CHAR buffer[BUFFSIZE]; //收发缓冲区
unsigned long recvBytes; //存储接收到的字节数
SOCKADDR_IN remoteAddr; //存储数据来源IP地址
int remoteAddrLen; //存储数据来源IP地址长度
BYTE type; //操作类型
}PER_IO_OPERATION_DATA, *LPPER_IO_OPERATION_DATA;
typedef struct _completion_key//完成键
{
SOCKET sock;
char sIP[30]; //本机测试,IP都是127.0.0.1,没啥意思,实际写时候这个值填的是端口号
}COMPLETION_KEY, *LP_COMPLETION_KEY;
void pp(char *str, int data)//显示到编辑框
{
char buf[256] = { 0 };
char buf1[16] = { 0 };
char buf2[8] = { 0 };
strcat(buf, str);
buf1[0] = 0x09;
_itoa_s(data, &buf1[1], 10, 16);
strcat(buf, buf1);
*(DWORD *)&buf2 = 0x0A0D;
strcat(buf, buf2);
SendMessage(hEdit, EM_SETSEL, -2, -1);
SendMessage(hEdit, EM_REPLACESEL, 0, (LPARAM)buf);
return;
}
DWORD WINAPI WorkerThread(LPVOID lpParam)//工作者线程------------------------------------------------------------------------------------------------------------------------
{
pp("工作者线程启动成功", (int)lpParam);
DWORD dwIoSize;
COMPLETION_KEY *lpComKey; //完成键
LPPER_IO_OPERATION_DATA lpIOData; //I/O数据
while (bRun)
{
dwIoSize = -1; // 字节数 完成键 OVERLAPPED结构 超时(函数返回0 WAIT_TIMEOUT)
if (GetQueuedCompletionStatus(hIocp, &dwIoSize, (LPDWORD)&lpComKey, (LPOVERLAPPED*)&lpIOData, INFINITE)) //成功非0
{
if (lpIOData->type == READ)// 收到数据 发送处理结果
{
pp(lpIOData->buffer, lpIOData->remoteAddr.sin_addr.S_un.S_addr);
pp("远程端口", lpIOData->remoteAddr.sin_port);
int len = sizeof(sockaddr_in);
DWORD flags = 0;
DWORD recvBytes = 0;
lpIOData = (LPPER_IO_OPERATION_DATA)GlobalAlloc(GPTR, sizeof(PER_IO_OPERATION_DATA));
lpIOData->DataBuff.buf = lpIOData->buffer;
lpIOData->DataBuff.len = BUFFSIZE;
WSARecvFrom(sListen, &(lpIOData->DataBuff), 1, &recvBytes, &flags, (sockaddr*)&(lpIOData->remoteAddr), sizeof(sockaddr_in), &(lpIOData->Overlapped), 0);
}
else if (lpIOData->type == WRITE)//数据已发送
{
pp("数据已发送断开客户", (int)lpComKey->sock);
}
}
else
{
DWORD dwIOError = GetLastError();
if (WAIT_TIMEOUT == dwIOError)
{
continue;
}
else if (NULL != lpIOData)
{
}
else
{
bRun = FALSE;
break;
}
}
}
pp("工作者线程退出", (int)lpParam);
return 0;
}
DWORD WINAPI TestThread(LPVOID lpParam)//测试线程
{
SOCKADDR_IN SockAddr;
SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (hSocket != SOCKET_ERROR)
{
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
SockAddr.sin_port = htons(5888);
if (connect(hSocket, (sockaddr*)&SockAddr, 16) != SOCKET_ERROR)
{
//pp("连接成功!", 0);
char buf[100] = "光阴的故事!\n";
if (SOCKET_ERROR == send(hSocket, buf, 100, 0))
{
pp("cannot SEND message to server!", WSAGetLastError());
}
//pp("发送成功!", 0);
memset(buf, 0, strlen(buf)); //清空一下,体现是接收到的数据
if (SOCKET_ERROR == recv(hSocket, buf, 100, 0))
{
pp("cannot RECV message to server!", WSAGetLastError());
}
//pp("接收成功!", 0);
closesocket(hSocket);
}
}
return 0;
}
LRESULT CALLBACK WndProc(HWND _hWnd, UINT message, WPARAM wParam, LPARAM lParam)//处理主窗口的消息 WM_COMMAND - 处理应用程序菜单 WM_PAINT - 绘制主窗口 WM_DESTROY - 发送退出消息并返回
{
switch (message)
{
case WM_COMMAND:
{
switch (LOWORD(wParam))// 分析菜单选择:
{
case 1025://开始按钮
{
pp("开始", 0);
WSADATA ws;
if (!WSAStartup(MAKEWORD(2, 2), &ws)) //初始化SOCKET
{
pp("初始化SOCKET成功", 0);
hIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); //初始化完成端口(句柄)
if (hIocp)
{
pp("初始化完成端口成功", (int)hIocp);
bRun = true;HANDLE ThreadHandle;SYSTEM_INFO SystemInfo;GetSystemInfo(&SystemInfo);
for (int i = 0; i < (int)SystemInfo.dwNumberOfProcessors; i++)
{
ThreadHandle = CreateThread(NULL, 0, &WorkerThread, (LPVOID)i, 0, NULL);
CloseHandle(ThreadHandle);
}
sListen = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); //创建监听套接字
if (sListen)
{
pp("创建监听套接字", (int)sListen);
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(5888);
if (bind(sListen, (PSOCKADDR)&InternetAddr, sizeof(InternetAddr)) == 0)
{
pp("绑定套接字端口", (int)InternetAddr.sin_port);
//将监听套接字与完成端口绑定
LP_COMPLETION_KEY pComKey; //完成键
pComKey = (LP_COMPLETION_KEY)GlobalAlloc(GPTR, sizeof(COMPLETION_KEY));
pComKey->sock = sListen;
CreateIoCompletionPort((HANDLE)sListen, hIocp, (DWORD)pComKey, 0);
LPPER_IO_OPERATION_DATA lpIOData;
int len = sizeof(sockaddr_in);
DWORD flags = 0;
DWORD recvBytes = 0;
lpIOData = (LPPER_IO_OPERATION_DATA)GlobalAlloc(GPTR, sizeof(PER_IO_OPERATION_DATA));
lpIOData->DataBuff.buf = lpIOData->buffer;
lpIOData->DataBuff.len = BUFFSIZE;
WSARecvFrom(sListen, &(lpIOData->DataBuff), 1, &recvBytes, &flags, (sockaddr*)&(lpIOData->remoteAddr), (LPINT)&len, &(lpIOData->Overlapped), 0);
}
}
}
}
}
break;
case 1026://停止按钮
{
bRun = FALSE;
closesocket(sListen);
CloseHandle(hIocp);
WSACleanup();
}
break;
case 1027://测试按钮
{
HANDLE ThreadHandle = CreateThread(NULL, 0, &TestThread, (LPVOID)0, 0, NULL);
CloseHandle(ThreadHandle);
}
break;
default:
break;
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(_hWnd, &ps);
EndPaint(_hWnd, &ps);
}
break;
case WM_CREATE://创建控件 组合框 编辑框12 按钮截包 停止 发送 -----------------------------------------------------------------------------------------------------------
{
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", nullptr, WS_CHILD + WS_VISIBLE + WS_VSCROLL + ES_MULTILINE, 8, 8, 450, 220, _hWnd, (HMENU)1024, hInst, nullptr);
hBtn_Start = CreateWindowEx(0, "button", "开始", WS_CHILD + WS_VISIBLE, 100, 240, 64, 32, _hWnd, (HMENU)1025, hInst, nullptr);
hBtn_Stop = CreateWindowEx(0, "button", "停止", WS_CHILD + WS_VISIBLE, 280, 240, 64, 32, _hWnd, (HMENU)1026, hInst, nullptr);
hBtn_Test = CreateWindowEx(0, "button", "测试", WS_CHILD + WS_VISIBLE, 380, 240, 64, 32, _hWnd, (HMENU)1027, hInst, nullptr);
}
break;
case WM_DESTROY://程序退出
{
PostQuitMessage(0);
}
break;
default:
return DefWindowProc(_hWnd, message, wParam, lParam);
}
return 0;
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{ // 执行应用程序初始化:
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
//MyRegisterClass(hInstance);
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbW