Windsock套接字I/O模型学习 --- 第三章
1. WSAAsyncSelect 模型
WSAAsyncSelect 模型比较简单,是为了适应Windows的消息驱动环境而设置的,WSAAsyncSelect 函数自动把套接字设为非阻塞模式。MFC( Microsoft Foundation Class, Microsoft 基础类库)中的CSocket 类也使用了它
2. 应用举例
// WSAAyncSelectDemo.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "WSAAyncSelectDemo.h"
#include <WinSock2.h>
#include <cstdlib>
#define MAX_LOADSTRING 100
#define WM_SOCKET (WM_USER + 100)
// Global Variables:
HINSTANCE hInst; // current instance
WCHAR szTitle[MAX_LOADSTRING]; // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
// Initialize global strings
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_WSAAYNCSELECT, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WSAAYNCSELECT));
MSG msg;
// Main message loop:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WSAAYNCSELECT));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WSAAYNCSELECT);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
USHORT nPort = 4567; // 此服务器监听的端口号
SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(nPort);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
if (::bind(sListen, (sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR)
{
return FALSE;
}
::WSAAsyncSelect(sListen, hWnd, WM_SOCKET, FD_ACCEPT | FD_CLOSE);
::listen(sListen, 5); // 进入监听模式
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SOCKET:
{
SOCKET s = wParam; // 取得有事件发生的套接字句柄
// 查看是否出错
if (WSAGETSELECTERROR(lParam))
{
::closesocket(s);
return 0;
}
// 处理发生的事件
switch (WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT: // 监听中的套接字检测到有连接进入
{
SOCKET client = ::accept(s, NULL, NULL);
::WSAAsyncSelect(client,
hWnd, WM_SOCKET, FD_READ | FD_WRITE | FD_CLOSE);
}
break;
case FD_WRITE:
{ }
break;
case FD_READ:
{
char szText[1024] = { 0 };
if (::recv(s, szText, 1024, 0) == -1)
::closesocket(s);
else
{
TCHAR szOut[256] = { 0 };
std::mbtowc(szOut, szText, strlen(szText));
OutputDebugString(szOut);
}
}
break;
case FD_CLOSE:
{
::closesocket(s); }
break;
}
}
break;
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code that uses hdc here...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
注:目前win32程序中
WSAAsyncSelect
已经是弃用的api,一般会推荐使用WSAEventSelect
,这个是接下来要说的一个I/O模型
Windsock套接字I/O模型学习 --- 第三章的更多相关文章
- Windsock套接字I/O模型学习 --- 第二章
1. select模型 select模型主要借助于apiselect来实现,所以先介绍一下select函数 int select( int nfds, // 忽略,仅是为了与 Berkeley 套接字 ...
- Windsock套接字I/O模型学习 --- 第一章
1. I/O模型共有以下几种: 阻塞(blocking)模型 选择(select)模型 WSAAsyncSelect模型 WSAEventSelect模型 重叠(overlapped)模型 完成端口( ...
- 套接字I/O模型之WSAEventSelect
今天我又学习了一种新的套接字I/O模型------WSAEventSelect,他与WSAAsyncSelect一样也是一种异步事件通知模型,不同的是WSAAsyncSelect是与窗口句柄关联在一起 ...
- 套接字I/O模型-select
共有6种类型套接字I/O模型.blocking(阻塞),select(选择),WSAAsyncSelect(异步选择),WSAEventSelect(事件选择),overlapped(重叠),comp ...
- 套接字I/O模型-重叠I/O
重叠模型的基本设计原理是让应用程序使用重叠的数据结构,一次投递一个或多个WinsockI/O请求.针对那些提交的请求,在它们完成之后,应用程序可为它们提供服务.模型的总体设计以Windows重叠I/O ...
- 套接字I/O模型-WSAAsyncSelect
利用这个异步I/O模型,应用程序可在一个套接字上接收以Windows消息为基础的网络事件通知.WSAAsyncSelect和WSAEventSelect提供读写数据能力的异步通知,但它们不提供异步数据 ...
- 套接字I/O模型-完成端口IOCP
“完成端口”模型是迄今为止最为复杂的一种I/O模型.然而,假若一个应用程序同时需要管理为数众多的套接字,那么采用这种模型,往往可以达到最佳的系统性能!但不幸的是,该模型只适用于Windows NT和W ...
- 套接字I/O模型-WSAEventSelect(转载)
和WSAAsyncSelect类似,它也允许应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知. 该模型最主要的区别是在于网络事件是由对象句柄完成的,而不是通过窗口例程完成. 事件通知 事件 ...
- Linux下套接字具体解释(三)----几种套接字I/O模型
參考: 网络编程–IO模型演示样例 几种server端IO模型的简介及实现 背景知识 堵塞和非堵塞 对于一个套接字的 I/O通信,它会涉及到两个系统对象.一个是调用这个IO的进程或者线程,还有一个就是 ...
随机推荐
- magento寄存器的使用
1.Mage::register('validation_image_name', $validationImageName);//这个是把变量$validationImageName存储在valid ...
- jquery实现页面内部的内容切换
html页面 .box-body-1-3 li{ margin: 20px; cursor: pointer; //实现鼠标放在上面是小手状态 } 点击列表 <div class=" ...
- 为什么 dll 改名字之后无法使用
有人直接把dll名字改了,我的程序运行出错,说这是我程序的问题,难道真是这样吗? 总感觉直接改dll名字不对,但哪儿不对呢,带着这样的疑惑研究了一下,重新做了一下试验,结果程序抛出了错误: Could ...
- ios 将彩色照片转化成黑白等几种类型
-(UIImage *)changeColoursImageTograyScaleImage:(UIImage *)anImage type:(int)type { CGImageRef imageR ...
- CSS设置input placeholder文本的样式
placeholder是HTML5 input的新属性,英文意思是占位符,它一般表示input输入框的默认提示值. 下面是设置placeholder的文本样式的选择器的示例: /* webkit 浏 ...
- Bourn Again Shell编程
shell既是命令解释程序,又是一种高级程序设计语言.shell是解释型语言. bash脚本的建立和运行: 注释行以#开头 #!后面的参数告诉系统执行本文件的程序 执行脚本文件有两种方法: 1. ...
- windows下如何快速搭建web.py开发框架
在windows下如何快速搭建web.py开发框架 用Python进行web开发的话有很多框架供选择,比如最出名的Django,tornado等,除了这些框架之外,有一个轻量级的框架使用起来也是非常方 ...
- web开发路径问题
1. web开发路径问题总结: http://www.cnblogs.com/tianguook/archive/2012/08/31/2665755.html 2. JSP/SERVLET 路径问题 ...
- Screen tearing
Umm, screen tearing happens when the frame rate and the monitor refresh rate don't match. When that ...
- eclipse中向左缩进快捷键
总是忘记,还是记下来吧,以后查找方便 Shift + Tab