WSAEventSelect Thread
void CWSAEvent02Dlg::OnBnClickedStartserver() { CString str; GetDlgItemText(IDC_StartServer, str); HWND hPaint = this->m_hWnd; if (str=="开始") { SetDlgItemText(IDC_StartServer,"停止"); //创建接受客户端请求线程 char dwThreadID[1024] = "3432432"; hThread=CreateThread(NULL,0,thread,(void*)m_hWnd,0,NULL); //SelectTcpSocket* stcp = new SelectTcpSocket; // stcp->run(); // delete stcp; } else { SetDlgItemText(IDC_StartServer,"开始"); ::CloseHandle(hThread); Sleep(100); WSACleanup(); } } DWORD WINAPI CWSAEvent02Dlg::thread(void *pParam) { /* CString* pToMyString = (CString*) pParam; CString str; str.Format(_T("%s"),pToMyString); AfxMessageBox(str); */ // TODO: 在此添加控件通知处理程序代码 CEdit* myeidt=(CEdit*)pParam;//新线程终于得到了编辑框的控制权。 CString edit_str; WORD wVersionRequested;//定义socket1.1或者socket2.0 WSADATA wsaData; //定义装载socket版本的变量 WSADATA m_wsaData; int err; //错误变量 wVersionRequested = MAKEWORD(2,2); //定义连接为socket2.0 err = WSAStartup(wVersionRequested, &m_wsaData); //装载socket2.0支持 // 事件句柄和套节字句柄表 WSAEVENT eventArray[WSA_MAXIMUM_WAIT_EVENTS]; SOCKET sockArray[WSA_MAXIMUM_WAIT_EVENTS]; int nEventTotal = 0; // 创建监听套节字 /* 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")); // AfxGetMainWnd()->GetDlgItem(IDC_EDIT3)->SetWindowText(edit_str); } else { //::AfxMessageBox(_T("bind success")); // AfxGetMainWnd()->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) { //AfxGetMainWnd()->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++; CString str13; str13="有客户已经连接上了"; AfxMessageBox(_T("有客户已经连接上了")); // AfxGetMainWnd()->SetWindowText(str13); // GetDlgItem(IDC_EDIT3)->EnableWindow(true); // AfxGetMainWnd()->GetDlgItem(IDC_EDIT3)->SetWindowText(str13); // GetDlgItem(IDC_EDIT1)->SetWindowText(str13); } } 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) { AfxMessageBox(nRecv); CString str2; str2+="\r\n"; str2 += (LPCTSTR)szText; // CString str = LPCTSTR(szText); //AfxMessageBox(str2); //MessageBox(LPCTSTR(szText)); //AfxGetMainWnd()->GetDlgItem(IDC_EDIT3)->SetWindowText(_T(szText)); // CWnd* pEdit; //CWnd* pEdit = ::GetDlgItem(IDC_EDIT3); //myeidt->SetWindowText(str); //::GetDlgItem(AfxGetMainWnd()->m_hWnd,IDC_EDIT3)->SetWindowText(szText); // ((CEdit*)GetDlgItem(IDC_EDIT3))); // recv(sListen,szText,1024,NULL); } } } 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通知消息 { } } } } return 0; }