WSASelectSevere.h
#pragma once
#define UM_ACCEPT WM_USER+1
#define UM_TALKING WM_USER+2
#define UM_USER WM_USER+3
#include"MyThread.h"
class WSASelectSevere
{
public:
WSASelectSevere(void);
~WSASelectSevere(void);
public :
bool StartSevere(HWND m_hWnd,short nPort=1234,CString nIp=_T("127.0.0.1"));
void StopSevere();
bool SendData(TCHAR *tzbuf,int nsize);
public:
SOCKET SocketListen;
HWND m_hParrentWnd;
SOCKET SocketWaiter;
CMyThread *m_thread;
public :
void OnAccept(WPARAM wparam ,LPARAM lparam);
void OnTalking(WPARAM wparam ,LPARAM lparam);
};
WSASelectSevere.cpp
#include "stdafx.h"
#include "WSASelectSevere.h"
#include"MyThread.h"
#include"MyWnd.h"
WSASelectSevere::WSASelectSevere(void)
{
m_thread=NULL;
SocketListen=NULL;
SocketWaiter=NULL;
m_hParrentWnd=NULL;
}
WSASelectSevere::~WSASelectSevere(void)
{
StopSevere();
}
bool WSASelectSevere::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;
}
//4.注册事件
//创建UI线程 1.需要一个线程类 CMyThread 继承 CwinThread
// 2.需要一个窗口类 窗口类处理接收的消息 CMyWnd 继承 CFrameWnd
// 3.在线程类中 CMyThread.cpp中的 InitStance 中 将 new CMyWnd 给 主窗口指针
// 窗口指针 创建一个不带界面的窗口
m_thread=(CMyThread *)AfxBeginThread(RUNTIME_CLASS(CMyThread));
Sleep(1000);//等待窗口创建完成
((CMyWnd*)m_thread->m_pMainWnd)->SetWSASelect(this);//将网络类的指针传到 窗口类中
WSAAsyncSelect(SocketListen,m_thread->m_pMainWnd->m_hWnd,UM_ACCEPT,FD_ACCEPT);//注册接收的是事件
//将消息发送到窗口中处理
return 1;
}
bool WSASelectSevere::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,szbuf,nsize,0))
{
return false;
}
//}
return true;
}
void WSASelectSevere::StopSevere()
{
WSACleanup();
if(SocketListen)
{
closesocket(SocketListen);
SocketListen=NULL;
}
if(SocketWaiter)
{
closesocket(SocketWaiter);
SocketWaiter=NULL;
}
}
void WSASelectSevere::OnAccept(WPARAM wparam ,LPARAM lparam)
{
SocketWaiter =accept(SocketListen,NULL/*客户端信息*/,NULL);
if(SocketWaiter!=INVALID_SOCKET)
{
TCHAR szbuf[1024]=_T("服务器链接成功");
SendMessage(m_hParrentWnd,UM_USER,(WPARAM)szbuf,1024);
WSAAsyncSelect(SocketWaiter,m_thread->m_pMainWnd->m_hWnd,UM_TALKING,FD_READ|FD_WRITE|FD_CLOSE);//注册事件
//将消息发送到窗口中处理
}
}
void WSASelectSevere::OnTalking(WPARAM wparam ,LPARAM lparam)
{
SOCKET SocketTemp = (SOCKET)wparam;
switch(LOWORD(lparam))
{
case FD_READ:
{
char szbuf[1024]={0};
TCHAR tzbuf[1024]={0};
int nres =recv(SocketTemp,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(m_hParrentWnd,UM_USER,(WPARAM)tzbuf,1024);
//pthis->m_lstbox.AddString(tzbuf);
}
}
break;
case FD_WRITE:
{
TRACE ("FD_WRITE \n");
}
break;
case FD_CLOSE:
{
TRACE("FD_CLOSE \n");
}
break;
}
}
MyWnd.h
#pragma once
#include"WSASelectSevere.h"
// CMyWnd 框架
class CMyWnd : public CFrameWnd
{
DECLARE_DYNCREATE(CMyWnd)
public:
CMyWnd();
virtual ~CMyWnd();
protected:
DECLARE_MESSAGE_MAP()
public :
LRESULT OnAccept(WPARAM wparam ,LPARAM lparam);
LRESULT OnTalking(WPARAM wparam ,LPARAM lparam);//窗口处理网络事件
void SetWSASelect(WSASelectSevere *severe)//获得网络类的指针
{
m_severe =severe;
}
WSASelectSevere *m_severe;
};
MyWnd.cpp
// MyWnd.cpp : 实现文件
//
#include "stdafx.h"
#include "severe.h"
#include "MyWnd.h"
// CMyWnd
IMPLEMENT_DYNCREATE(CMyWnd, CFrameWnd)
CMyWnd::CMyWnd()
{
}
CMyWnd::~CMyWnd()
{
}
BEGIN_MESSAGE_MAP(CMyWnd, CFrameWnd)
ON_MESSAGE(UM_ACCEPT,&CMyWnd::OnAccept)
ON_MESSAGE(UM_TALKING,&CMyWnd::OnTalking)
END_MESSAGE_MAP()
LRESULT CMyWnd::OnAccept(WPARAM wparam ,LPARAM lparam)//需要用到网络的中的东西太多 所以在网络类中 处理
{
if(m_severe)
{
m_severe->OnAccept(wparam,lparam);
}
return 1l;
}
LRESULT CMyWnd::OnTalking(WPARAM wparam ,LPARAM lparam)
{
if(m_severe)
{
m_severe->OnTalking(wparam,lparam);
}
return 1l;
}
// CMyWnd 消息处理程序
MyThread.h
#pragma once
// CMyThread
class CMyThread : public CWinThread
{
DECLARE_DYNCREATE(CMyThread)
protected:
CMyThread(); // 动态创建所使用的受保护的构造函数
virtual ~CMyThread();
public:
virtual BOOL InitInstance();
virtual int ExitInstance();
protected:
DECLARE_MESSAGE_MAP()
};
MyThred.cpp
// MyThread.cpp : 实现文件
//
#include "stdafx.h"
#include "severe.h"
#include "MyThread.h"
#include"MyWnd.h"
// CMyThread
IMPLEMENT_DYNCREATE(CMyThread, CWinThread)
CMyThread::CMyThread()
{
}
CMyThread::~CMyThread()
{
}
BOOL CMyThread::InitInstance()
{
// TODO: 在此执行任意逐线程初始化
m_pMainWnd=new CMyWnd;
((CFrameWnd*)m_pMainWnd)->Create(NULL/*类的名字*/,_T("mywnd"));
return TRUE;
}
int CMyThread::ExitInstance()
{
// TODO: 在此执行任意逐线程清理
return CWinThread::ExitInstance();
}
BEGIN_MESSAGE_MAP(CMyThread, CWinThread)
END_MESSAGE_MAP()
// CMyThread 消息处理程序