您的位置:首页 > 其它

Windows Socket五种I/O模型——序言

2009-08-19 09:55 369 查看
Windows Socket五种I/O模型——序言

http://blog.csdn.net/cq1982/archive/2007/05/27/1627545.aspx

初识windows网络编程,最近一直在研究如何使用套接字(socket)进行通信,仅以此文整理近来所学: (感谢各网友分享的资料)

Windows操作系统提供了选择(Select)、异步选择(WSAAsyncSelect)、事件选择(WSAEventSelect)、
重叠I/O(Overlapped I/O)和完成端口(Completion Port)共五种I/O模型。

一、时序图
在介绍I/O模型之前,我们先来看看基于TCP协议的套接字(socket)通信程序的时序图:



二、入门程序(可惜不是hello world)

现在,我给大家介绍一个网上很多地方介绍到的一个程序,开始我们的套接字(socket)编程之旅:

#include <Winsock2.h>
#include <stdio.h>

#pragma comment(lib, "ws2_32.lib")
#define PORT 8000

using namespace std;
SOCKET sockSVC;
SOCKET sockConnect;

DWORD WINAPI RecvData(
LPVOID lpParameter // thread data
);

void main()
...{
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 2, 2 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) ...{
return;
}

if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) ...{
WSACleanup();
return;
}

sockSVC = socket(AF_INET, SOCK_STREAM, 0);

SOCKADDR_IN addrSVC;
addrSVC.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSVC.sin_family = AF_INET;
addrSVC.sin_port = htons(PORT);

bind(sockSVC, (SOCKADDR*)&addrSVC, sizeof(SOCKADDR));

listen(sockSVC, 5);

SOCKADDR_IN addrClient;
int length = sizeof(SOCKADDR);

while(1)
...{
sockConnect = accept(sockSVC, (SOCKADDR*)&addrClient, &length);
if(INVALID_SOCKET !=sockConnect)
...{
HANDLE hThread;
hThread=CreateThread(NULL,0,RecvData,(LPVOID)sockConnect,0,NULL);
CloseHandle(hThread);
}
}

Sleep(INFINITE);
closesocket(sockConnect);
WSACleanup();
}

DWORD WINAPI RecvData(LPVOID lpParameter)
...{
SOCKET socket = (unsigned int)lpParameter;
char recVBuffer[1024];
for(;;)
...{
//receive data from client
if(SOCKET_ERROR == recv(socket, recVBuffer, 1024, 0))
...{
printf("The receive data defeat or was the Proxy Server side already withdraws... ");
break;
}
printf("Proxy Server says: %s", recVBuffer);
}
closesocket(socket);
return 0;
}
对于如初始化网络、建立监听套接字、绑定端口等等一些,很多地方都可以查到很详尽的注释,基本上以后用多了自然就烂熟于心了= =||

既然我们是要来谈I/O模型,这里倒是有一个很重要是思想可以来看看,这个程序调用Createthread为每个新的连接创建了一个单独的线程,并将一个连接好的套接字sockConnect作为参数传给了线程函数RecvData,这里为什么要这么处理呢?

网络通讯的主要任务是进行数据的传输,正是由于I/O操作在网络模型中极其重要的地位和其占用服务器处理时间比重较大的特点,本例将接收数据的任务交给子线程去处理,而服务器的主线程在进行一系列初始化等操作后就只用专心的等待新的连接请求就可以了。如此一来,岂不是各司其职、天下太平~~

至少,目前来看,这样的模型看上去还是很美的~~(真不想从这样的梦里醒来啊- -、)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: