MySockt.h #pragma once #define MAXNUM 64 #include<WinSock2.h> #pragma comment(lib,"ws2_32.lib") #define UM_USER WM_USER+1 //向窗口发消息 enum NETTYPE { NETRECV,NETACCEPT,NETSEND }; class CMySocket { public: CMySocket(void); ~CMySocket(void); public : static DWORD WINAPI ThreadAccept(LPVOID lpvoid); static DWORD WINAPI ThreadRecv(LPVOID lpvoid); public : bool StartSevere(HWND m_hWnd,short nPort=1234,CString nIp=_T("127.0.0.1")); void StopSevere(); bool SendData(TCHAR *tzbuf,int nsize); bool SelectSocket(SOCKET SocketWaiter,NETTYPE type); public : HANDLE m_hThreadAccept; HANDLE m_hThreadRecv; HANDLE m_hEventQuit; HANDLE m_hThreadAcceptCheck; HANDLE m_hThreadRecvCheck; HWND m_hParrentWnd; public : int m_num; SOCKET SocketListen; NETTYPE type; SOCKET SocketWaiter[MAXNUM]; }; MySocket.cpp #include "stdafx.h" #include "MySocket.h" CMySocket::CMySocket(void) { m_hThreadAccept = NULL; m_hThreadRecv= NULL; m_hEventQuit= NULL; m_hThreadAcceptCheck= NULL; m_hThreadRecvCheck= NULL; m_hParrentWnd=NULL; m_num=0; ZeroMemory(SocketWaiter,sizeof(SocketWaiter)); } CMySocket::~CMySocket(void) { StopSevere(); } void CMySocket::StopSevere() { WSACleanup(); for(int i=0;i<m_num;i++) { if(SocketWaiter[i]) { closesocket(SocketWaiter[i]); SocketWaiter[i]=NULL; } } if(SocketListen) { closesocket(SocketListen); SocketListen=NULL; } SetEvent(m_hEventQuit); if(WAIT_OBJECT_0 !=WaitForSingleObject(m_hThreadAcceptCheck,100)) { ::TerminateThread(m_hThreadAccept,-1); m_hThreadAccept=NULL; } if(WAIT_OBJECT_0 !=WaitForSingleObject(m_hThreadRecvCheck,100)) { ::TerminateThread(m_hThreadRecv,-1); m_hThreadRecv=NULL; } if(m_hEventQuit) { CloseHandle(m_hEventQuit); m_hEventQuit=NULL; } if(m_hThreadAcceptCheck) { CloseHandle(m_hThreadAcceptCheck); m_hThreadAcceptCheck=NULL; } if(m_hThreadRecvCheck) { CloseHandle(m_hThreadRecvCheck); m_hThreadRecvCheck=NULL; } } DWORD WINAPI CMySocket::ThreadAccept(LPVOID lpvoid) { CMySocket *pthis=(CMySocket*)lpvoid; while(1) { if( WAIT_OBJECT_0 == WaitForSingleObject(pthis->m_hEventQuit,100)) { break; } pthis->SocketWaiter[pthis->m_num]=accept(pthis->SocketListen,NULL,NULL); if(INVALID_SOCKET==pthis->SocketWaiter[pthis->m_num]) { pthis->StopSevere(); } pthis->m_num++; TCHAR szbuf[1024]=_T("服务器链接成功"); SendMessage(pthis->m_hParrentWnd,UM_USER,(WPARAM)szbuf,1024); //pthis->m_lstbox.AddString(szbuf); } SetEvent(pthis->m_hThreadAcceptCheck); return 0; } DWORD WINAPI CMySocket::ThreadRecv(LPVOID lpvoid) { CMySocket *pthis=(CMySocket*)lpvoid; while(1) { if( WAIT_OBJECT_0 == WaitForSingleObject(pthis->m_hEventQuit,100)) { break; } char szbuf[1024]={0}; TCHAR tzbuf[1024]={0}; for(int i=0;i<pthis->m_num;i++) { if(pthis->SelectSocket(pthis->SocketWaiter[i],NETRECV)) { int nres =recv(pthis->SocketWaiter[i],szbuf,1024,0); if(0!=nres &&SOCKET_ERROR !=nres) { #ifdef _UNICODE MultiByteToWideChar(CP_ACP,0,szbuf,-1,tzbuf,1024); #else strcpy_s(tzbuf,1024,szbuf); #endif SendMessage(pthis->m_hParrentWnd,UM_USER,(WPARAM)tzbuf,1024); //pthis->m_lstbox.AddString(tzbuf); } } } } SetEvent(pthis->m_hThreadRecvCheck); return 0; } bool CMySocket::StartSevere(HWND m_hWnd,short nPort,CString nIp) { m_hParrentWnd=m_hWnd; //0.加载库 WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return 0; } if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { WSACleanup( ); return 0; } //1.创建socket与外界通信的接口 SocketListen=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(INVALID_SOCKET==SocketListen) { StopSevere(); return 0; } //2.bind sockaddr_in addrsock; addrsock.sin_family=AF_INET; addrsock.sin_port=htons(nPort); char szbuf[1024]; #ifdef _UNICODE WideCharToMultiByte(CP_ACP,0,nIp,-1,szbuf,1024,0,0); #else strcpy_s(szbuf,1024,nIP); #endif addrsock.sin_addr.s_addr=inet_addr(szbuf); int nsize=sizeof(sockaddr_in); if(SOCKET_ERROR==bind(SocketListen,(const struct sockaddr*)&addrsock,nsize)) { StopSevere(); return 0; } //3.listen 监听 if(SOCKET_ERROR==listen(SocketListen,10)) { StopSevere(); return 0; } m_hEventQuit=::CreateEvent(NULL,TRUE,FALSE,NULL); m_hThreadAcceptCheck=::CreateEvent(NULL,TRUE,FALSE,NULL); m_hThreadRecvCheck=::CreateEvent(NULL,TRUE,FALSE,NULL); m_hThreadAccept=::CreateThread(NULL,0,&CMySocket::ThreadAccept,this,0,NULL); m_hThreadRecv=::CreateThread(NULL,0,&CMySocket::ThreadRecv,this,0,NULL); if(!m_hEventQuit||!m_hThreadAcceptCheck||!m_hThreadRecvCheck||!m_hThreadAccept||!m_hThreadRecv) { StopSevere(); return 0; } return 1; } bool CMySocket::SendData(TCHAR *tzbuf,int nsize) { if(!tzbuf||nsize<0) { return false; } char szbuf[1024]={0}; #ifdef _UNICODE WideCharToMultiByte(CP_ACP,0,tzbuf,-1,szbuf,1024,0,0); #else strcpy_s(szbuf,1024,tzbuf); #endif for(int i=0;i<m_num;i++) { if(SOCKET_ERROR==send(SocketWaiter[i],szbuf,nsize,0)) { return false; } } return true; } bool CMySocket::SelectSocket(SOCKET SocketWaiter,NETTYPE type) { if(!SocketWaiter) { return false; } TIMEVAL tv; tv.tv_sec=0; tv.tv_usec=100; //定义一个集合 fd_set fdsets; //清空集合 FD_ZERO(&fdsets); //将SocketWaiter加入到集合 FD_SET(SocketWaiter,&fdsets); //将集合交由select管理 if(type==NETACCEPT||type==NETRECV) { select(0,&fdsets,0,0,&tv); } else if(type==NETSEND) { select(0,0,&fdsets,0,&tv); } //校验SocketWaiter是否在集合 if(FD_ISSET(SocketWaiter,&fdsets)) { return TRUE; } else { return FALSE; } return true; }