SocketI/O模型--WSAAsyncSelect模型

SocketI/O模型–WSAAsyncSelect模型
分类: 网络与安全
http://hi.baidu.com/firebird/blog/item/f592b3193a02814542a9adeb.html
转:http://neora.javaeye.com/blog/402336
//
/// WSAAsyncSelect模型(同步I/O模型)
///这里为什么说他是同步的,就是因为实际的数据的Copy是同步进行///的,而不是异步的,只是相应的通知机制(通知数据已经准备好了),///是异步的
/// 这个模型允许应用程序以Windows消息的形式可在一个套接字上,接收网络事件通知
/// 具体的做法是在建好一个套接字后,调用WSAAsyncSelect函数。
/// 在我看来,WSAAsyncSelect是最简单的一种Winsock I/O模型(之所以说它简单是
/// 因为一个主线程就搞定了)。
/// 这里,我们需要做的仅仅是:
/// 1.在WM_CREATE消息处理函数中,初始化Windows Socket library,创建监听套接字,绑定,
/// 监听,并且调用WSAAsyncSelect函数表示我们关心在监听套接字上发生的FD_ACCEPT事件;
/// 2.自定义一个消息WM_SOCKET,一旦在我们所关心的套接字(监听套接字和客户端套接字)上
/// 发生了某个事件,系统就会调用WndProc并且message参数被设置为WM_SOCKET;
/// 3.在WM_SOCKET的消息处理函数中,分别对FD_ACCEPT、FD_READ和FD_CLOSE事件进行处理;
/// 4.在窗口销毁消息(WM_DESTROY)的处理函数中,我们关闭监听套接字,清除Windows Socket library
//
/// 老陈:服务器应用程序,微软:服务器操作系统
/// 老陈使用了微软公司的新式信箱。这种信箱非常先进,一旦信箱里有新的信件,盖茨就会给
/// 老陈打电话:喂,大爷,你有新的信件了!从此,老陈再也不必频繁上下楼检查信箱了,牙
// 也不疼了,你瞅准了,蓝天……不是,微软……
/// 微软提供的WSAAsyncSelect模型就是这个意思。
//
/// The WSAAsyncSelect function requests Windows message-based notification of network
/// events for a socket.
//

pragma once

include

include

define PORT 5150

define MSGSIZE 1024

define WM_SOCKET WM_USER+0

pragma comment(lib, “ws2_32.lib”)

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = _T(“AsyncSelect Model”);
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass(&wndclass))
{
MessageBox (NULL, TEXT (“This program requires Windows NT!”), szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, // window class name

TEXT (“AsyncSelect Model”), // window caption

WS_OVERLAPPEDWINDOW, // window style

CW_USEDEFAULT, // initial x position

CW_USEDEFAULT, // initial y position

CW_USEDEFAULT, // initial x size

CW_USEDEFAULT, // initial y size

NULL, // parent window handle

NULL, // window menu handle

hInstance, // program instance handle

NULL) ; // creation parameters

ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg) ;
DispatchMessage(&msg) ;
}
return msg.wParam;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
WSADATA wsd;
static SOCKET sListen;
SOCKET sClient;
SOCKADDR_IN local, client;
int ret, iAddrSize = sizeof(client);
char szMessage[MSGSIZE];
switch (message)
{
case WM_CREATE:
// Initialize Windows Socket library

WSAStartup(0x0202, &wsd);
// Create listening socket

sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// Bind

local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(PORT);
bind(sListen, (struct sockaddr *)&local, sizeof(local));
// Listen

listen(sListen, 3);
// Associate listening socket with FD_ACCEPT event

WSAAsyncSelect(sListen, hwnd, WM_SOCKET, FD_ACCEPT);
return 0;
case WM_DESTROY:
closesocket(sListen);
WSACleanup();
PostQuitMessage(0);
return 0;
case WM_SOCKET:
if (WSAGETSELECTERROR(lParam))
{
closesocket(wParam);
break;
}
switch (WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
// Accept a connection from client

sClient = accept(wParam, (struct sockaddr *)&client, &iAddrSize);
// Associate client socket with FD_READ and FD_CLOSE event

WSAAsyncSelect(sClient, hwnd, WM_SOCKET, FD_READ | FD_CLOSE);
break;
case FD_READ:
ret = recv(wParam, szMessage, MSGSIZE, 0);
if (ret == 0 || ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET)
{
closesocket(wParam);
}
else
{
szMessage[ret] = ‘\0’;
send(wParam, szMessage, strlen(szMessage), 0);
}
break;
case FD_CLOSE:
closesocket(wParam);
break;
}
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值