WSAevent
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WSAevent相关的知识,希望对你有一定的参考价值。
// TODO: 在此添加控件通知处理程序代码 CString str,edit_str; GetDlgItemText(IDC_StartServer, str); // 事件句柄和套节字句柄表 WSAEVENT eventArray[WSA_MAXIMUM_WAIT_EVENTS]; SOCKET sockArray[WSA_MAXIMUM_WAIT_EVENTS]; int nEventTotal = 0; if (str=="开始") { SetDlgItemText(IDC_StartServer,_T("停止")); // 创建监听套节字 /* Enable address reuse */ int ret; char on; on = 1; USHORT nPort = 4567; // 此服务器监听的端口号 SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); ret = setsockopt( sListen, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ); sockaddr_in sin; memset( &sin, 0, sizeof(sin) ); sin.sin_family = AF_INET; sin.sin_port = htons(nPort); sin.sin_addr.S_un.S_addr = INADDR_ANY; if(::bind(sListen, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR) { edit_str= " Failed bind()"; // ::AfxMessageBox(_T("Failed bind")); GetDlgItem(IDC_EDIT3)->SetWindowText(edit_str); } else { //::AfxMessageBox(_T("bind success")); GetDlgItem(IDC_EDIT3)->SetWindowText(_T("bind success!")); } ::listen(sListen, 5); // 创建事件对象,并关联到新的套节字 WSAEVENT event = ::WSACreateEvent(); ::WSAEventSelect(sListen, event, FD_ACCEPT|FD_CLOSE); // 添加到表中 eventArray[nEventTotal] = event; sockArray[nEventTotal] = sListen; nEventTotal++; // 处理网络事件 while(TRUE) { // 在所有事件对象上等待 int nIndex = ::WSAWaitForMultipleEvents(nEventTotal, eventArray, FALSE, WSA_INFINITE, FALSE); // 对每个事件调用WSAWaitForMultipleEvents函数,以便确定它的状态 nIndex = nIndex - WSA_WAIT_EVENT_0;//发生的事件对象的索引,一般是句柄数组中最前面的那一个,然后再用循环依次处理后面的事件对象 for(int i=nIndex; i<nEventTotal; i++) { int ret; ret = ::WSAWaitForMultipleEvents(1, &eventArray[i], TRUE, 1000, FALSE); if(ret == WSA_WAIT_FAILED || ret == WSA_WAIT_TIMEOUT) { continue; } else { // 获取到来的通知消息,WSAEnumNetworkEvents函数会自动重置受信事件 WSANETWORKEVENTS event; ::WSAEnumNetworkEvents(sockArray[i], eventArray[i], &event); if(event.lNetworkEvents & FD_ACCEPT) // 处理FD_ACCEPT通知消息 { if(event.iErrorCode[FD_ACCEPT_BIT] == 0) { if(nEventTotal > WSA_MAXIMUM_WAIT_EVENTS) { GetDlgItem(IDC_EDIT1)->SetWindowText(_T(" Too many connections!")); // printf(" Too many connections! /n"); continue; } SOCKET sNew = ::accept(sockArray[i], NULL, NULL); WSAEVENT event = ::WSACreateEvent(); ::WSAEventSelect(sNew, event, FD_READ|FD_CLOSE|FD_WRITE); // 添加到表中 eventArray[nEventTotal] = event; sockArray[nEventTotal] = sNew; nEventTotal++; } } else if(event.lNetworkEvents & FD_READ) // 处理FD_READ通知消息 { if(event.iErrorCode[FD_READ_BIT] == 0) { char szText[1024]; int nRecv = ::recv(sockArray[i], szText, strlen(szText), 0); if(nRecv > 0) { MessageBox(LPCTSTR(szText)); szText[nRecv] = ‘\0‘; } } } else if(event.lNetworkEvents & FD_CLOSE) // 处理FD_CLOSE通知消息 { if(event.iErrorCode[FD_CLOSE_BIT] == 0) { ::closesocket(sockArray[i]); for(int j=i; j<nEventTotal-1; j++) { sockArray[j] = sockArray[j+1]; sockArray[j] = sockArray[j+1]; } nEventTotal--; } } else if(event.lNetworkEvents & FD_WRITE) // 处理FD_WRITE通知消息 { } } } } } else { SetDlgItemText(IDC_StartServer,_T("开始")); }
以上是关于WSAevent的主要内容,如果未能解决你的问题,请参考以下文章