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模型学习 --- 第三章的更多相关文章

  1. Windsock套接字I/O模型学习 --- 第二章

    1. select模型 select模型主要借助于apiselect来实现,所以先介绍一下select函数 int select( int nfds, // 忽略,仅是为了与 Berkeley 套接字 ...

  2. Windsock套接字I/O模型学习 --- 第一章

    1. I/O模型共有以下几种: 阻塞(blocking)模型 选择(select)模型 WSAAsyncSelect模型 WSAEventSelect模型 重叠(overlapped)模型 完成端口( ...

  3. 套接字I/O模型之WSAEventSelect

    今天我又学习了一种新的套接字I/O模型------WSAEventSelect,他与WSAAsyncSelect一样也是一种异步事件通知模型,不同的是WSAAsyncSelect是与窗口句柄关联在一起 ...

  4. 套接字I/O模型-select

    共有6种类型套接字I/O模型.blocking(阻塞),select(选择),WSAAsyncSelect(异步选择),WSAEventSelect(事件选择),overlapped(重叠),comp ...

  5. 套接字I/O模型-重叠I/O

    重叠模型的基本设计原理是让应用程序使用重叠的数据结构,一次投递一个或多个WinsockI/O请求.针对那些提交的请求,在它们完成之后,应用程序可为它们提供服务.模型的总体设计以Windows重叠I/O ...

  6. 套接字I/O模型-WSAAsyncSelect

    利用这个异步I/O模型,应用程序可在一个套接字上接收以Windows消息为基础的网络事件通知.WSAAsyncSelect和WSAEventSelect提供读写数据能力的异步通知,但它们不提供异步数据 ...

  7. 套接字I/O模型-完成端口IOCP

    “完成端口”模型是迄今为止最为复杂的一种I/O模型.然而,假若一个应用程序同时需要管理为数众多的套接字,那么采用这种模型,往往可以达到最佳的系统性能!但不幸的是,该模型只适用于Windows NT和W ...

  8. 套接字I/O模型-WSAEventSelect(转载)

    和WSAAsyncSelect类似,它也允许应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知. 该模型最主要的区别是在于网络事件是由对象句柄完成的,而不是通过窗口例程完成. 事件通知 事件 ...

  9. Linux下套接字具体解释(三)----几种套接字I/O模型

    參考: 网络编程–IO模型演示样例 几种server端IO模型的简介及实现 背景知识 堵塞和非堵塞 对于一个套接字的 I/O通信,它会涉及到两个系统对象.一个是调用这个IO的进程或者线程,还有一个就是 ...

随机推荐

  1. JS+CSS简单实现DIV遮罩层显示隐藏

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. jQuery技巧大放送【转】

    1.关于页面元素的引用 通过jquery的$()引用元素包括通过id.class.元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用do ...

  3. MongoDB文档基本操作

    一.插入文档 使用insert()或save()方法向集合插入文档 >db.COLLECTION_NAME.insert(document) 详细用法可以参考MongoDB菜鸟教程 二.查找文档 ...

  4. Maven项目问题

    Maven项目部署 svn检出的为普通项目 1.普通项目转换为Maven项目: 选择项目右击->Maven4MyEclipse->Update Project 2.tomcat项目空间WE ...

  5. 1、java面试

    1.为什么用单例而不用static 答案:首先你要明白static是在什么时候初始化的,其设计意图是什么,单例就是我们运行的当前虚拟机中有且只有一个需要的对象,不存在重复.static是给类静态成员变 ...

  6. Java的I/O总结

    概念:Java语言中数据流是接收和发送数据的管道.流是一位单项的. 流的分类: 按照字节字符:InputStream和OutputStream是字节输入输出流的抽象父类.Reader和Writer是字 ...

  7. MvcPager

    站点网址:http://www.webdiyer.com/mvcpager/ 控制台命令:Install-Package Webdiyer.MvcPager

  8. RPM安装gcc gcc-c++扩展

    rpm -ivh cpp--.el5.i386.rpm 回车 rpm -ivh kernel-headers--.el5.i386.rpm 回车 rpm -ivh glibc-headers-.i38 ...

  9. IE6下a标签失效(背景穿透)

    background:fixed url(about:blank);有时候做感应区域的时候在ie6下不给背景就会感应不到,比如说当鼠标移到图片的左半边部分,鼠标手势变成向左的箭 头,比如说有些时候a标 ...

  10. Flask -- 消息闪现、错误处理

    flash 可以在任何需要的地方添加,类似于print from flask import flash @app.route('/') def index(): flash('You are in h ...