您的位置:首页 > 理论基础 > 计算机网络

Select网络模型

2015-10-09 13:47 441 查看
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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: