Windows套接字I/O模型
来源:互联网 发布:mmd双人动作数据下载 编辑:程序博客网 时间:2024/06/03 07:57
两中模式执行I/O操作
阻塞模式:执行I/O的Winsock调用(如send和recv),一直到操作完成才返回。
非阻塞模式:Winsock函数会立即返回
1.select(选择)模型
1>增加一个套接字集合fd
2>设置一个可读或者可写的套接字集合fd1
3>使用select函数(可设置等待的时长)获得有I/O操作的套接字集合fd1
4>处理这些I/O
可以理解为:假设有10个快递要取,我隔断时间就去快递站去看有没有我的快递,如果有我就拿回来,如果没有我也立刻回来,重复如此。
2.WSAAsyncSelect模型(异步选择模型)(需要建立一个窗口用于接收消息)
以windows消息的形式接收网络事件通知
可以理解为:我不需要隔段时间就去看快递有没有到,如果快递到了,快递公司打电话给我,我再去拿快递
3.WSAEventSelect模型(事件选择模型)
接受网络事件,不是依靠Windows消息驱动机制,而是经由事件对象句柄通知
1>创建一个事件句柄表和一个对应的套接字句柄表
2>每创建一个套接字就创建一个事件对象,把它们的句柄分别放入到上面的两个表中,并调用WSAEventSelect添加它们的关联
3>调用WSAWaitForMultipleEvents在所有事件对象上等待,以便确认哪些套接字上发生了网络事件
4>处理发生的网络事件,继续在事件对象上等待
可以理解为:有点类似WSAAsyncSelect模型,但是它不需要消息通知,它将套接字和网络事件及事件对象绑定了在一起。就相当于我在快递站安装了一个监测器,如果快递到了,检测器就会发出通知,就不用快递公司一个一个的打电话。
4.重叠(Overlapped)I/O模型
由于读写操作太慢,应用程序不想等待,可以设置一个缓冲区,让操作系统完成读写操作,等完成了再来通知应用程序
可以理解为:快递公司直接将快递送到我家门口,到我家了再通知我开门签收,误区自己去快递公司
5.完成端口模型(iocp)
IOCP采用了线程池(提前创建好线程,更有效)+队列+重叠结构的内核机制完成任务
1>创建完成端口对象
2>创建一个或者多个工作线程(I/O服务线程)
3>将套接字关联到完成端口对象
4>套接字向完成端口提交各种所需请求
5>在完成端口上等待的线程池处理这些I/O
#include"CInitSock.h"CInitSock init;#define BUFFER_SIZE 1024typedef struct _PER_HANDLE_DATA{ SOCKET s; sockaddr_in addr;}PER_HANDLE_DATA,*PPER_HANDLE_DATA;typedef struct _PER_IO_DATA{ OVERLAPPED ol; char buf[BUFFER_SIZE]; int nOperationType;#define OP_READ 1#define OP_WRITE 2#define OP_ACCEPT 3}PER_IO_DATA, *PPER_IO_DATA;DWORD WINAPI ServerThread(LPVOID lpParam);int main(){ int nPort = 4567; HANDLE hCompletion = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0); CreateThread(NULL, 0, ServerThread, (LPVOID)hCompletion, 0, 0); SOCKET sListen = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN si; si.sin_family = AF_INET; si.sin_port = ntohs(nPort); si.sin_addr.S_un.S_addr = INADDR_ANY; bind(sListen, (sockaddr*)&si, sizeof(si)); listen(sListen, 5); while (TRUE) { SOCKADDR_IN saRemote; int nRemoteLen = sizeof(saRemote); SOCKET sNew = accept(sListen, (sockaddr*)&saRemote, &nRemoteLen); cout << "接收到" <<inet_ntoa(saRemote.sin_addr) << "的连接" << endl; PPER_HANDLE_DATA pPerHandle = (PPER_HANDLE_DATA)GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA)); pPerHandle->s=sNew; memcpy(&pPerHandle->addr, &saRemote, nRemoteLen); CreateIoCompletionPort((HANDLE)pPerHandle->s, hCompletion, (DWORD)pPerHandle, 0); PPER_IO_DATA pPerIO = (PPER_IO_DATA)GlobalAlloc(GPTR, sizeof(PER_IO_DATA)); pPerIO->nOperationType = OP_READ; WSABUF buf; buf.buf = pPerIO->buf; buf.len = BUFFER_SIZE; DWORD dwRecv; DWORD dwFlags = 0; WSARecv(pPerHandle->s, &buf, 1, &dwRecv, &dwFlags, &pPerIO->ol, NULL); }}DWORD WINAPI ServerThread(LPVOID lpParam){ HANDLE hCompletion = (HANDLE)lpParam; DWORD dwTrans; PPER_HANDLE_DATA pPerHandle; PPER_IO_DATA pPerIO; while (TRUE) { BOOL bOK = GetQueuedCompletionStatus(hCompletion, &dwTrans, (LPDWORD)&pPerHandle, (LPOVERLAPPED*)&pPerIO, WSA_INFINITE); if (!bOK) { closesocket(pPerHandle->s); GlobalFree(pPerHandle); GlobalFree(pPerIO); continue; } if (dwTrans == 0 && (pPerIO->nOperationType == OP_READ || pPerIO->nOperationType == OP_WRITE)) { closesocket(pPerHandle->s); GlobalFree(pPerHandle); GlobalFree(pPerIO); continue; } switch (pPerIO->nOperationType) { case OP_READ: { pPerIO->buf[dwTrans] = '\0'; cout << inet_ntoa(pPerHandle->addr.sin_addr) << ":"; cout << pPerIO->buf<<endl; WSABUF buf; buf.buf = pPerIO->buf; buf.len = BUFFER_SIZE; pPerIO->nOperationType = OP_READ; DWORD nFlags = 0; WSARecv(pPerHandle->s, &buf, 1, &dwTrans, &nFlags, &pPerIO->ol, NULL); } break; case OP_WRITE: case OP_ACCEPT:break; } } return 0;}
- Windows套接字I/O模型
- Windows套接字I/O 模型
- Windows 套接字I/O 模型
- windows套接字I/O模型
- Windows 套接字I/O 模型
- Windows套接字I/O模型
- Windows套接字I/O模型之套接字模式
- Windows套接字I/O模型(1) -- 阻塞模型
- Windows套接字I/O模型(2) -- Select模型
- Windows套接字I/O模型(3) -- WSAAsyncSelect模型
- Windows套接字I/O模型(4) -- WSAEventSelect模型
- 套接字i/o模型
- 套接字I/O模型
- 套接字I/O模型
- 套接字I/O模型
- Windows套接字I/O模型(1) 套接字模式
- 套接字I/O模型之WSAEventSelect
- 套接字之重叠I/O模型
- Python入门系列——第8篇
- java堆栈
- Linux终端tty设备驱动
- 使用codeblock 编译工程发出警告:"Debug" uses an invalid compiler. Skipping...
- caffe的finetuning是如何更新网络参数的
- Windows套接字I/O模型
- Perl中system的返回值问题
- Linux下安装Nginx
- linux的内存管理方式
- linux下安装python3对应的setuptools、pip和其他包
- 图像分割“RefineNet-Multi-Path Refinement Networks for High-Resolution Semantic Segmentation”
- HDU--dp练习--1013--免费馅饼
- POJ 2346 Lucky tickets(数位dp求前几位数字和)
- h5 css3笔记