windows重叠模式
2015-12-23 15:52
155 查看
1.WSASocket介绍
SOCKET WSASocket (
int af,
int type,
int protocol,
LPWSAPROTOCOL_INFO lpProtocolInfo,
GROUP g,
DWORD dwFlags
);
af:只支持AF_INET;
type:新套接口的类型描述。SOCK_STREAM tcp,SOCK_DGRAM udp。
lpProtocolInfo:一个指向PROTOCOL_INFO结构的指针,该结构定义所创建套接口的特性。如果本参数非零,则前三个参数(af, type, protocol)被忽略。
dwFlags :套接口属性描述
2.重叠IO创建
重叠的数据结构(WSAOVERLAPPED),一次投递一个或多个 Winsock I/O 请求。
创建套接字重叠IO套接字
SOCKET s=WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
win上使用socket创建socket默认设置WSA_FLAG_OVERLAPPED标志
3.重叠IO使用
WSASend // sends data on a connected socket. 提供一个指向已填充的数据缓冲区的指针。
WSASendTo // sends data to a specific destination, using overlapped I/O where applicable.
WSARecv // receives data from a connected socket.
WSARecvFrom //receives data on a socket and stores the source address. 提供存放接收数据的缓冲区
WSAIoctl //allows for miscellaneous control of a socket. 还可以使用重叠I/O操作的延迟完成特性。
AcceptEx //accepts a new connection, returns the local and remote address, and receives the first block of data sent by the client application.
TrnasmitFile //transmits file data over a connected socket handle. uses the operating system's cache manager to retrieve the file data, and provides high-performance file data transfer over sockets.
这里面WS_IO_PENDING 是最常见的返回值,这是说明我们的重叠函数调用成功了,但是I/O操作还没有完成。
如果和一个WSAOVERLAPPED结构一起来调用这些函数,那么函数会立即完成并返回,无论套接字是否是阻塞模式。判断I/O请求是否成功的方法有两个,分别是:
1、等待 事件对象通知。
2、通过 完成例程。
4.实例
SOCKET WSASocket (
int af,
int type,
int protocol,
LPWSAPROTOCOL_INFO lpProtocolInfo,
GROUP g,
DWORD dwFlags
);
af:只支持AF_INET;
type:新套接口的类型描述。SOCK_STREAM tcp,SOCK_DGRAM udp。
lpProtocolInfo:一个指向PROTOCOL_INFO结构的指针,该结构定义所创建套接口的特性。如果本参数非零,则前三个参数(af, type, protocol)被忽略。
dwFlags :套接口属性描述
2.重叠IO创建
重叠的数据结构(WSAOVERLAPPED),一次投递一个或多个 Winsock I/O 请求。
创建套接字重叠IO套接字
SOCKET s=WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
win上使用socket创建socket默认设置WSA_FLAG_OVERLAPPED标志
3.重叠IO使用
WSASend // sends data on a connected socket. 提供一个指向已填充的数据缓冲区的指针。
WSASendTo // sends data to a specific destination, using overlapped I/O where applicable.
WSARecv // receives data from a connected socket.
WSARecvFrom //receives data on a socket and stores the source address. 提供存放接收数据的缓冲区
WSAIoctl //allows for miscellaneous control of a socket. 还可以使用重叠I/O操作的延迟完成特性。
AcceptEx //accepts a new connection, returns the local and remote address, and receives the first block of data sent by the client application.
TrnasmitFile //transmits file data over a connected socket handle. uses the operating system's cache manager to retrieve the file data, and provides high-performance file data transfer over sockets.
这里面WS_IO_PENDING 是最常见的返回值,这是说明我们的重叠函数调用成功了,但是I/O操作还没有完成。
如果和一个WSAOVERLAPPED结构一起来调用这些函数,那么函数会立即完成并返回,无论套接字是否是阻塞模式。判断I/O请求是否成功的方法有两个,分别是:
1、等待 事件对象通知。
2、通过 完成例程。
4.实例
#include "stdafx.h" #include <stdio.h> #include <afx.h> #include <winsock2.h> #define DATA_BUFSIZE 1024 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) { SOCKET ListenSocket,AcceptSocket; WSAOVERLAPPED AcceptOverlapped; WSABUF DataBuf; WSADATA wsaData; WSAStartup(MAKEWORD(2,2),&wsaData); ListenSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//创建TCP套接字 SOCKADDR_IN ServerAddr;//分配端口及协议族并绑定 ServerAddr.sin_family=AF_INET; ServerAddr.sin_addr.S_un.S_addr =htonl(INADDR_ANY); ServerAddr.sin_port=htons(8888); bind(ListenSocket,(LPSOCKADDR)&ServerAddr, sizeof(ServerAddr));//绑定套接字 listen(ListenSocket, 5); SOCKADDR_IN ClientAddr;// 定义一个客户端得地址结构作为参数 int addr_length=sizeof(ClientAddr); WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS]; DWORD dwEventTotal = 0, dwRecvBytes = 0, Flags = 0; AcceptSocket = accept(ListenSocket,(SOCKADDR*)&ClientAddr, &addr_length); LPCTSTR lpIP = inet_ntoa(ClientAddr.sin_addr);// IP UINT nPort = ClientAddr.sin_port;// Port //为接受的套接字创建一个WSAOVERLAPPED结构,并给这个结构分配一个事件对象句柄,同时将该事件对象句柄分配给一个事件数组,以便稍后WSAWaitForMultipleEvents函数使用 EventArray[dwEventTotal] = WSACreateEvent(); ZeroMemory(&AcceptOverlapped, sizeof(WSAOVERLAPPED)); AcceptOverlapped.hEvent = EventArray[dwEventTotal]; char buffer[DATA_BUFSIZE]; ZeroMemory(buffer, DATA_BUFSIZE); DataBuf.len = DATA_BUFSIZE; DataBuf.buf = buffer; dwEventTotal ++; if(WSARecv(AcceptSocket ,(WSABUF *)&DataBuf,1,&dwRecvBytes,&Flags,&AcceptOverlapped,NULL) == SOCKET_ERROR) { if(WSAGetLastError() != WSA_IO_PENDING) { closesocket(AcceptSocket); WSACloseEvent(EventArray[dwEventTotal]); } } while(1) { DWORD dwIndex; dwIndex = WSAWaitForMultipleEvents(dwEventTotal, EventArray ,FALSE ,WSA_INFINITE,FALSE); // 注意这里返回的Index并非是事件在数组里的Index,而是需要减去WSA_WAIT_EVENT_0 dwIndex = dwIndex - WSA_WAIT_EVENT_0; WSAResetEvent(EventArray[dwIndex]); if(WSARecv(AcceptSocket ,&DataBuf,1,&dwRecvBytes,&Flags,&AcceptOverlapped, NULL) == SOCKET_ERROR) { if(WSAGetLastError() != WSA_IO_PENDING) { closesocket(AcceptSocket); WSACloseEvent(EventArray[dwEventTotal]); } TRACE("dwRecvBytes = %2d\n",dwRecvBytes); } } return 0; }
相关文章推荐
- 如何在阿里云服务器搭建FTP服务器,在本地电脑连接并操作
- mysql5.6安装mysql-workbench
- 国家语言代码
- java多线程问题总结
- swift学习之基础语法
- 定时器的实现
- Habber - IOS XMPP 客户端 教程 (终)总结与反思
- NSDate总结 (学习笔记)
- Java获取电脑IP,MAC,各种版本
- (三)开关检测来控制LED灯的亮灭
- java 线程池
- 不同版本Lua介绍
- SDL 与 FFMPEG 音乐播放器开发(3)——改变音量、跳转
- 使用iframe实现提交表单不刷新页面
- <iOS>Git简史
- 查看系统自带的RPM
- display: -webkit-flex; 手机上图下文字,pad上有浮动。
- Android Fragment(碎片)的使用
- ubuntu linux 下wine的使用
- ubuntu 14.0.4LTS安装LNMP php7.0(主要用于个人笔记 勿喷)