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

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

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

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值