本文实例讲述了C++中WSAAsyncSelect模型的用法。分享给大家供大家参考。具体实现方法如下:
TCPServer.cpp源文件如下:
#include "resource.h"
#define WM_SOCKET WM_USER+1
CMyApp theApp;
BOOL CMyApp::InitInstance()
{
//初始化套接字
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2,0);
::WSAStartup(wVersionRequested, &wsaData);
//显示对话框
CMainDialog dlg;
m_pMainWnd = &dlg;
dlg.DoModal();
//释放套接字
::WSACleanup();
return FALSE;
}
//CMainDialog
CMainDialog::CMainDialog(CWnd* pParentWnd):CDialog(IDD_MAINDIALOG,pParentWnd)
{
}
BEGIN_MESSAGE_MAP(CMainDialog, CDialog)
ON_BN_CLICKED(IDC_START, OnStart)
ON_BN_CLICKED(IDC_CLEAR, OnClear)
ON_MESSAGE(WM_SOCKET, OnSocket)
END_MESSAGE_MAP()
void CMainDialog::OnCancel()
{
this->CloseAllSocket();
CDialog::OnCancel();
}
BOOL CMainDialog::OnInitDialog()
{
CDialog::OnInitDialog();
//设置图标
SetIcon(theApp.LoadIconA(IDI_MAIN), FALSE);
//创建状态栏并设置其属性
m_bar.Create(WS_CHILD|WS_VISIBLE|SBS_SIZEGRIP, CRect(0,0,0,0), this, 101);
m_bar.SetBkColor(RGB(0xa6, 0xca, 0xfa));
int arWidth[]={200,-1};
m_bar.SetParts(2, arWidth);
m_bar.SetText("windows程序设计", 1, 0);
m_bar.SetText("空闲", 0, 0);
//关联列表控件
m_listInfo.SubclassDlgItem(IDC_LIST, this);
//初始化套接字和连接列表
m_socket = INVALID_SOCKET;
m_nClient = 0;
//取得本机IP,在状态栏中显示
char szHostName[MAX_PATH] = {0};
::gethostname(szHostName, MAX_PATH);
hostent *pHost = gethostbyname(szHostName);
if (pHost != NULL)
{
CString strIP;
in_addr* addr = (in_addr*)*pHost->h_addr_list;
strIP.Format("本机IP:%s",inet_ntoa(addr[0]));
m_bar.SetText(strIP, 0, 0);
}
return TRUE;
}
BOOL CMainDialog::CreateAndListen(int nPort)
{
if (m_socket == INVALID_SOCKET)
{
::closesocket(m_socket);
}
//创建套接字
m_socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_socket == INVALID_SOCKET)
{
return FALSE;
}
//绑定端口
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(nPort);
//sin.sin_addr.S_un.S_addr = INADDR_ANY;
sin.sin_addr.s_addr = INADDR_ANY;
int nErr = GetLastError();
if (::bind(m_socket, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
{
nErr = GetLastError();
return FALSE;
}
::WSAAsyncSelect(m_socket, m_hWnd, WM_SOCKET, FD_ACCEPT|FD_CLOSE|FD_READ);
//进入监听模式
::listen(m_socket, 5);
return TRUE;
}
BOOL CMainDialog::AddClient(SOCKET s)
{
if (m_nClient < MAX_SOCKET)
{
m_arClient[m_nClient++] = s;
return TRUE;
}
return FALSE;
}
void CMainDialog::RemoveClient(SOCKET s)
{
BOOL bFound = FALSE;
int i;
for (i=0;i<m_nClient;i++)
{
if (m_arClient[i] == s)
{
bFound = TRUE;
break;
}
}
//找到
if (bFound)
{
m_nClient--;
for (int j=i;j<m_nClient;j++)
{
m_arClient[j] = m_arClient[j+1];
}
}
}
void CMainDialog::CloseAllSocket()
{
if (m_socket != INVALID_SOCKET)
{
::closesocket(m_socket);
m_socket = INVALID_SOCKET;
}
for (int i=0;i<m_nClient;i++)
{
::closesocket(m_arClient[i]);
}
m_nClient = 0;
}
void CMainDialog::OnStart()
{
if (m_socket == INVALID_SOCKET) //开启服