当前位置: 首页 > news >正文

怎么建立网站?自己做彩票网站

怎么建立网站?,自己做彩票网站,微信小程序认证入口,access 数据库做网站简介 WSAEventSelect 模型也是 WinSock 中最常见的异步 I/O 模型。 这篇文章我们就来看看如何使用 WSAEventSelect api 来实现一个简单的 TCP 服务器. API 基础 WSAEventSelect WSAEventSelect 用来把一个 SOCKET 对象和一个 WSAEVENT 对象关联起来。 lNetworkEvents 表示…简介 WSAEventSelect 模型也是 WinSock 中最常见的异步 I/O 模型。 这篇文章我们就来看看如何使用 WSAEventSelect api 来实现一个简单的 TCP 服务器. API 基础 WSAEventSelect WSAEventSelect 用来把一个 SOCKET 对象和一个 WSAEVENT 对象关联起来。 lNetworkEvents 表示我们关心的 FD_XXX 网络事件. 如果关心多个 SOCKET 事件可以使用 OR 的方式指定多个 FD_XXX 标志。 int WSAAPI WSAEventSelect(SOCKET s,WSAEVENT hEventObject,long lNetworkEvents );当特定的事件发生在相应的 SOCKET 上该 SOCKET 上接下来的事件将会被阻塞直到当前的事件被应用处理. 该事件被处理之后接下来的事件将可以被进一步触发. 事件处理函数FD_READrecv, recvFrom, WSARecv, WSARecvEx, WSARecvFromFD_WRITEsend, sendTo, WSASend, WSASentToFD_OOBrecv, recvFrom, WSARecv, WSARecvEx, WSARecvFromFD_ACCEPTaccept, AcceptEx, WSAAcceptFD_CONNECTNoneFD_CLOSENoneFD_QOSWSAIoctl (with SIO_GET_QOS)FD_GROUP_QOSReservedFD_ROUTINE_INTERFACE_CHANGEWSAIoctl (with SIO_ROUTINE_INTERFACE_CHANGE)FD_ADDRESS_LIST_CHANGEWSAIoctl (with SIO_ADDRESS_LIST_CHANGE) WSAEvent WSACreateEvent 方法用来创建一个 WSAEvent 对象 WSAEVENT WSAAPI WSACreateEvent();WSAWaitForMultipleEvents 用于等待一组事件中的一个或全部被触发。 DWORD WSAAPI WSAWaitForMultipleEvents(DWORD cEvents,const WSAEVENT *lphEvents,BOOL fWaitAll,DWORD dwTimeout,BOOL fAlertable );cEvents指定 lphEvents 数组中事件对象的数量。 该参数的最大值是 WSA_MAXIMUM_WAIT_EVENTS 64lphEvents事件对象的集合fWaitAll: 指定等待 lphEvents 中所有事件被触发或者其中之一被触发。 如果指定为 TRUE 那么该函数只有在所有事件对象都被触发之后才会返回。 如果指定为 FALSE 当事件集合中任何一个事件被触发之后该方法就会返回。如果在这种情况下有多个事件对象被触发那个返回值将会返回该事件集合中索引值最小的索引值. 索引值减去 WSA_WAIT_EVENT_0 便是指向 lphEvents 中被触发的事件的索引值.dwTimeout: 如果在 timeout 事件间隔内没有事件被触发函数不会一直阻塞而是在等待 timeout 毫秒后返回。 指定该参数为 WSA_INFINITE 该函数会一直等待直到有事件被触发. 指定该参数为 0 该函数会立即返回.fAlertable: 略 WSAEnumNetworkEvents 用于查询当前 SOCKET 上触发事件对象 hEventObject 的对应 socket 事件FD_READ, FD_WRITE 等. int WSAAPI WSAEnumNetworkEvents(SOCKET s,WSAEVENT hEventObject,LPWSANETWORKEVENTS lpNetworkEvents );实现思路 创建一个 socket 作为监听 socket使用 WSAEventSelect 监听该 SOCKET 上的网络事件使用 WSAWaitForMultipleEvents 等待 SOCKET 事件当 SOCKET 上有事件被触发使用 WSAEnumNetworkEvents 查询具体的 SOCKET 事件并使用相应的 API 处理事件.当有新的 SOCKET 连接到来接收该连接重复 2-4 步骤. 实例 接下来我们通过一个实例来看看如何实现. #include winsock2.h #include windows.h #include stdio.h#pragma comment(lib,ws2_32.lib)#define PORT 8080 #define DATA_BUFSIZE 8192typedef struct _SOCKET_CONTEXT {CHAR Buffer[DATA_BUFSIZE];WSABUF DataBuf;SOCKET Socket;DWORD BytesSEND;DWORD BytesRECV; } SOCKET_CONTEXT, * LPSOCKET_CONTEXT;BOOL CreateSocketInformation(SOCKET s); void FreeSocketInformation(DWORD Event);// 这里我们维护了如下数据结构 // EeventArray 我们为每个 SOCKET 对象创建一个对应的事件对象以便我们能监听该 SOCKET 上的网络事件 // SocketArray 毫无疑问我们也需要维护所有SOCKET连接的的数组。其中包含 Listen SocketDWORD EventTotal 0; WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS]; LPSOCKET_CONTEXT SocketArray[WSA_MAXIMUM_WAIT_EVENTS];int main() {SOCKET ListenSocket;SOCKET AcceptSocket;SOCKADDR_IN Addr;LPSOCKET_CONTEXT SocketContext;WSANETWORKEVENTS NetworkEvents;DWORD Event;WSADATA wsaData;DWORD Flags;DWORD RecvBytes;DWORD SendBytes;// 初始化 Listen Socket 对象if (WSAStartup(0x0202, wsaData) ! 0) {printf(WSAStartup() failed with error %d\n, WSAGetLastError());return 1;}if ((ListenSocket socket(AF_INET, SOCK_STREAM, 0)) INVALID_SOCKET) {printf(socket() failed with error %d\n, WSAGetLastError());return 1;}if (CreateSocketInformation(ListenSocket) FALSE) {printf(CreateSocketInformation() failed!\n);return 1;}// 在调用 listen api 之前我们需要使用 WSAEventSelect 需要将 ListenSocket 与一个 WSAEvent 对象关联起来这里我们仅仅关系 FD_ACCEPT 和 FS_CLOSE 事件.// 当这两个事件之一被触发我们编译可以从 EventArray[0] 上查询到这些实际以便进行处理if (WSAEventSelect(ListenSocket, EventArray[EventTotal - 1], FD_ACCEPT | FD_CLOSE) SOCKET_ERROR) {printf(WSAEventSelect() failed with error %d\n, WSAGetLastError());return 1;}Addr.sin_family AF_INET;Addr.sin_addr.s_addr htonl(INADDR_ANY);Addr.sin_port htons(PORT);if (bind(ListenSocket, (PSOCKADDR) Addr, sizeof(Addr)) SOCKET_ERROR) {printf(bind() failed with error %d\n, WSAGetLastError());return 1;}if (listen(ListenSocket, 10)) {printf(listen() failed with error %d\n, WSAGetLastError());return 1;}while(TRUE) {// 等待当前所有 socket 上的网络事件被触发//// 这里我们 fWait FALSE 也就是说任何一个 SOCKET 上有网络之间// 我们便停止等待开始处理该事件//// dwTimeout WSA_INFINITE 如果没有网络事件发生我们就一直等待// 直到有网络事件发生//// 这里 EventTotal 会随着客户端连接的到来增加同时我们会创建对应的 Event对象// 并放入 EventArrayif ((Event WSAWaitForMultipleWSAWaitForEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE)) WSA_WAIT_FAILED) {printf(WSAWaitForMultipleEvents() failed with error %d\n, WSAGetLastError());return 1;}// 程序运行到这里已经有网络事件发生了我们使用WSAEnumNetworkEvents 查询到底是什么网络事件 // 查询结果保存在 NetworkEvents 对象上// 注意在 API 章节我们已经说明WSAWaitForMultipleWSAWaitForEvents 的返回值减去 WSA_WAIT_EVENT_0 才是对应的 EventArray 中被触发的事件的索引值if (WSAEnumNetworkEvents(SocketArray[Event - WSA_WAIT_EVENT_0]-Socket,EventArray[Event - WSA_WAIT_EVENT_0], NetworkEvents) SOCKET_ERROR) {printf(WSAEnumNetworkEvents() failed with error %d\n, WSAGetLastError());return 1;}// 检查当前事件是否是 FD_ACCEPT// 如果是 FD_ACCEPT事件使用 accept 接收新的连接。if (NetworkEvents.lNetworkEvents FD_ACCEPT) {if (NetworkEvents.iErrorCode[FD_ACCEPT_BIT] ! 0) {printf(FD_ACCEPT failed with error %d\n, NetworkEvents.iErrorCode[FD_ACCEPT_BIT]);break;}if ((AcceptSocket accept(SocketArray[Event - WSA_WAIT_EVENT_0]-Socket, NULL, NULL)) INVALID_SOCKET) {printf(accept() failed with error %d\n, WSAGetLastError());break;}if (EventTotal WSA_MAXIMUM_WAIT_EVENTS) {printf(Too many connections - closing socket...\n);closesocket(AcceptSocket);break;}// 接收新的连接之后为该 SOCKET 创建 WSAEvent对象在CreateSocketInformation 实现// 然后监听该 SOCKET 的 FD_READ, FD_WRITE, FD_CLOSE 事件CreateSocketInformation(AcceptSocket);if (WSAEventSelect(AcceptSocket, EventArray[EventTotal - 1], FD_READ|FD_WRITE|FD_CLOSE) SOCKET_ERROR) {printf(WSAEventSelect() failed with error %d\n, WSAGetLastError());return 1;}printf(Socket %d got connected...\n, AcceptSocket);}// 检查当前事件是否是 FD_READ 或者 FD_WRITEif (NetworkEvents.lNetworkEvents FD_READ || NetworkEvents.lNetworkEvents FD_WRITE) {// 检查是不是发生了读错误if (NetworkEvents.lNetworkEvents FD_READ NetworkEvents.iErrorCode[FD_READ_BIT] ! 0) {printf(FD_READ failed with error %d\n, NetworkEvents.iErrorCode[FD_READ_BIT]);break;}// 检查是不是发生了写错误if (NetworkEvents.lNetworkEvents FD_WRITE NetworkEvents.iErrorCode[FD_WRITE_BIT] ! 0) {printf(FD_WRITE failed with error %d\n, NetworkEvents.iErrorCode[FD_WRITE_BIT]);break;}SocketContext SocketArray[Event - WSA_WAIT_EVENT_0];// Read data only if the receive buffer is emptyif (SocketContext-BytesRECV 0) {SocketContext-DataBuf.buf SocketContext-Buffer;SocketContext-DataBuf.len DATA_BUFSIZE;Flags 0;if (WSARecv(SocketContext-Socket, (SocketContext-DataBuf), 1, RecvBytes, Flags, NULL, NULL) SOCKET_ERROR) {if (WSAGetLastError() ! WSAEWOULDBLOCK) {printf(WSARecv() failed with error %d\n, WSAGetLastError());FreeSocketInformation(Event - WSA_WAIT_EVENT_0);return 1;}} else {printf(WSARecv() is working!\n);SocketContext-BytesRECV RecvBytes;}}if (SocketContext-BytesRECV SocketContext-BytesSEND) {SocketContext-DataBuf.buf SocketContext-Buffer SocketContext-BytesSEND;SocketContext-DataBuf.len SocketContext-BytesRECV - SocketContext-BytesSEND;if (WSASend(SocketContext-Socket, (SocketContext-DataBuf), 1, SendBytes, 0, NULL, NULL) SOCKET_ERROR) {if (WSAGetLastError() ! WSAEWOULDBLOCK) {printf(WSASend() failed with error %d\n, WSAGetLastError());FreeSocketInformation(Event - WSA_WAIT_EVENT_0);return 1;}// A WSAEWOULDBLOCK error has occurred. An FD_WRITE event will be posted// when more buffer space becomes available} else {printf(WSASend() is fine! Thank you...\n);SocketContext-BytesSEND SendBytes;if (SocketContext-BytesSEND SocketContext-BytesRECV) {SocketContext-BytesSEND 0;SocketContext-BytesRECV 0;}}}}// 检查当前事件是否是 FD_CLOSEif (NetworkEvents.lNetworkEvents FD_CLOSE) {// 检查是否发生了错误if (NetworkEvents.iErrorCode[FD_CLOSE_BIT] ! 0) {printf(FD_CLOSE failed with error %d\n, NetworkEvents.iErrorCode[FD_CLOSE_BIT]);break;} else {// socket 正常关闭printf(FD_CLOSE is OK!\n);}printf(Closing socket information %d\n, SocketArray[Event - WSA_WAIT_EVENT_0]-Socket);FreeSocketInformation(Event - WSA_WAIT_EVENT_0);}}return 0; }BOOL CreateSocketInformation(SOCKET s) {LPSOCKET_CONTEXT SocketContext;if ((EventArray[EventTotal] WSACreateEvent()) WSA_INVALID_EVENT) {printf(WSACreateEvent() failed with error %d\n, WSAGetLastError());return FALSE;}if ((SocketContext (LPSOCKET_CONTEXT) GlobalAlloc(GPTR, sizeof(SOCKET_CONTEXT))) NULL) {printf(GlobalAlloc() failed with error %d\n, GetLastError());return FALSE;}// Prepare SocketInfo structure for useSocketContext-Socket s;SocketContext-BytesSEND 0;SocketContext-BytesRECV 0;SocketArray[EventTotal] SocketContext;EventTotal;return TRUE; }void FreeSocketInformation(DWORD Event) {LPSOCKET_CONTEXT SocketContext SocketArray[Event];DWORD i;closesocket(SocketContext-Socket);GlobalFree(SocketContext);if(WSACloseEvent(EventArray[Event]) TRUE) {printf(WSACloseEvent() is OK!\n\n);}// Squash the socket and event arraysfor (i Event; i EventTotal; i) {EventArray[i] EventArray[i 1];SocketArray[i] SocketArray[i 1];}EventTotal--; }END
http://www.zqtcl.cn/news/96155/

相关文章:

  • 网站建设设计团队平面设计主要做什么ui
  • 站长工具seo综合查询广告和京东一样的网站
  • 柳州做网站的企业做黑彩网站
  • 商城网站开发那家好网站建设知识平台
  • 莱州网站定制flash网站cms
  • 经营范围里的网站建设直播系统程序
  • 58同城类似的网站开发wordpress 地方生活
  • wordpress 七牛ossseo系统
  • 郑州做网站 熊掌号太原今天最新通知
  • 文章网站如何与压力做足球比赛直播间在线观看
  • 越秀网站建设优化呼和浩特住房和城乡建设部网站
  • 河南省路桥建设集团网站建网站公司郑州
  • 海沧做网站深圳外贸招聘
  • 网站建设置顶多少钱翻译成英文
  • 柳州正规网站制作公司哪家好怎么学好网站建设
  • 德宏做网站网站的设计思路范文
  • 自己的电脑做网站服务器深圳福田有什么好玩的地方
  • 奕腾网站建设上海十大装修公司排名榜单
  • 简述建设一个网站的基本步骤wordpress欢迎新会员
  • 国外医疗网站模板wordpress主题 科技
  • 海淀企业型网站建设wordpress自定义帖子链接
  • 自己的网站怎么优化做网页的
  • dw设计一个简单网站网页微信版文件传输
  • 网站地图怎么做XML宁波网站建设服务提供商
  • 中石化两学一做网站获取网站域名
  • 吉林长春火车站官网湖北葛洲坝建设工程网站
  • 重庆网站推广服务广告公司女员工深夜兼职
  • 网站的要素是什么wordpress框架解密_day3
  • 抽奖怎么做网站彩页设计公司
  • 推广网站文案素材lamp环境wordpress