This article illustrates the use of the WSAAsyncSelect model in C + +. Share to everyone for your reference. The implementation methods are as follows:
TCPServer.cpp source files are as follows:
Copy Code code as follows:
#include "TCPServer.h"
#include "resource.h"
#define Wm_socket wm_user+1
CMyApp Theapp;
BOOL cmyapp::initinstance ()
{
Initializing sockets
Wsadata Wsadata;
WORD wversionrequested = Makeword (2,0);
:: WSAStartup (wversionrequested, &wsadata);
Show dialog box
Cmaindialog Dlg;
m_pMainWnd = &dlg;
Dlg. DoModal ();
Releasing sockets
:: 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 ();
Set icon
SetIcon (Theapp.loadicona (Idi_main), FALSE);
Create a status bar and set its properties
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 Programming", 1, 0);
M_bar. SetText ("Free", 0, 0);
Association list control
M_listinfo.subclassdlgitem (idc_list, this);
Initializing Sockets and Connection lists
M_socket = Invalid_socket;
m_nclient = 0;
Get native IP, display in the status bar
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 ("Local 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);
}
Creating sockets
M_socket =:: Socket (af_inet, sock_stream, ipproto_tcp);
if (M_socket = = Invalid_socket)
{
return FALSE;
}
Binding ports
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);
Enter listening mode
:: 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
}
}
Found it
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)//Open service
{
CString Strport;
GetDlgItem (Idc_port)->getwindowtext (Strport);
int nport = atoi (Strport);
if (Nport < 1 | | | nport >65535)
{
MessageBox ("Port error");
Return
}
Creating sockets
if (!this->createandlisten (Nport))
{
MessageBox ("Create socket Error");
Return
}
Setting control state
GetDlgItem (Idc_start)->setwindowtexta ("Stop Service");
M_bar. SetText ("Listening ...", 0, 0);
GetDlgItem (Idc_port)->enablewindow (FALSE);
}
else//Close service
{
Closeallsocket ();
GetDlgItem (Idc_start)->setwindowtexta ("Open service");
M_bar. SetText ("Free", 0, 0);
GetDlgItem (Idc_port)->enablewindow (TRUE);
}
return;
}
void Cmaindialog::onclear ()
{
M_listinfo.resetcontent ();
return;
}
Long Cmaindialog::onsocket (WPARAM WPARAM, LPARAM LPARAM)
{
Get handle
SOCKET s = wParam;
See if there is an error
if (Wsagetselecterror (LParam))
{
Removeclient (s);
:: Closesocket (s);
return 0;
}
Handling events that occurred
Switch (wsagetselectevent (lParam))
{
Case FD_ACCEPT://Supervisor heard there is a connection in the socket
{
MessageBox ("server:accept");
if (M_nclient < Max_socket)
{
SOCKET client =:: Accept (S, null, NULL);
This->addclient (client);
}
Else
{
MessageBox ("Too many Connection");
}
}
Break
Case Fd_close:
{
MessageBox ("Server:close");
Removeclient (s);
Closesocket (s);
}
Break
Case Fd_read://Receive packets from each other
{
MessageBox ("Server:read");
Get the address of each other
Sockaddr_in sockaddr;
memset (&sockaddr, 0, sizeof (SOCKADDR));
int nsockaddrlength = sizeof (SOCKADDR);
:: Getpeername (S, (sockaddr*) &sockaddr, &nsockaddrlength);
int npeerport = Ntohs (Sockaddr.sin_port);
CString StrIP = Inet_ntoa (SOCKADDR.SIN_ADDR); StrIP
Get host Name
DWORD Dwip =:: inet_addr (StrIP);
hostent* Phost =:: Gethostbyaddr ((LPSTR) &dwip, 4, af_inet);
Char szhostname[256]={0};
strncpy (Szhostname, Phost->h_name, 256);
Get Network data
Char szcontent[1024]={0};
:: Recv (S, szcontent, 1024, 0);
Show
CString stritem = CString (szhostname) + "[" + StrIP +]: "+ CString (szcontent);
M_listinfo.insertstring (0, stritem);
}
Break
}
return 0;
}
TCPServer.h header files are as follows:
Copy Code code as follows:
#include <afxwin.h>
#include <afxext.h>//cstatusbar
#include <WinSock2.h>
#include <afxcmn.h>
#pragma comment (lib, "Ws2_32.lib")
#define Max_socket 56//MAX Customer Volume
Class Cmyapp:public CWINAPP
{
Public
BOOL InitInstance ();
};
Cmaindialog
Class Cmaindialog:public CDialog
{
Public
Cmaindialog (cwnd* pparentwnd=null);
Protected
Virtual BOOL OnInitDialog ();
virtual void OnCancel ();
Turn on or off a service
afx_msg void OnStart ();
afx_msg void OnClear ();
afx_msg Long Onsocket (WPARAM WPARAM, LPARAM LPARAM);
BOOL createandlisten (int nport);
Add a customer to the Customer connection list
BOOL addclient (SOCKET s);
Remove a customer from the Customer connection list
void Removeclient (SOCKET s);
Close all connections
void Closeallsocket ();
Protected
SOCKET M_socket;
Two child window controls
CListBox M_listinfo;
CStatusBarCtrl M_bar;
Customer Connection List
SOCKET M_arclient[max_socket]; Socket list
int m_nclient; The size of the array above
Declare_message_map ()
};
TCPClient.cpp source files are as follows:
Copy Code code as follows:
#include "TCPClient.h"
#include "resource.h"
#define Wm_socket wm_user+1
CMyApp Theapp;
BOOL cmyapp::initinstance ()
{
Initializing sockets
Wsadata Wsadata;
WORD wversionrequested = Makeword (2,0);
:: WSAStartup (wversionrequested, &wsadata);
Show dialog box
Cmaindialog Dlg;
m_pMainWnd = &dlg;
Dlg. DoModal ();
Releasing sockets
:: WSACleanup ();
return FALSE;
}
Cmaindialog
Cmaindialog::cmaindialog (cwnd* pParentWnd): CDialog (Idd_maindialog,pparentwnd)
{
}
Begin_message_map (Cmaindialog, CDialog)
On_bn_clicked (Idc_connect, OnConnect)
On_bn_clicked (Idc_send, OnSend)
On_message (Wm_socket, Onsocket)
End_message_map ()
void Cmaindialog::oncancel ()
{
Cdialog::oncancel ();
}
BOOL Cmaindialog::oninitdialog ()
{
CDialog::OnInitDialog ();
Set icon
SetIcon (Theapp.loadicona (Idi_main), FALSE);
Associated controls
M_edit_text. SubclassDlgItem (idc_edit_content, this);
Status bar
M_bar. Create (ws_child| ws_visible| Sbs_sizegrip, CRect (0, 0, 0,0), this, NULL);
int nwidth[]={100,-1};
M_bar. SetParts (2, nwidth);
M_bar. SetText ("Windows Programming", 1, 0);
M_bar. SetText ("Free", 0, 0);
GetDlgItem (IDC_ADDR)->setwindowtexta ("192.168.19.143");
GetDlgItem (Idc_port)->setwindowtexta ("9999");
//
M_socket = Invalid_socket;
return TRUE;
}
void Cmaindialog::addstringtolist (CString strText)
{
CString strcontent;
GetDlgItem (idc_edit_content)->getwindowtext (strcontent);
GetDlgItem (idc_edit_content)->setwindowtext (Strcontent+strtext);
}
Long Cmaindialog::onsocket (WPARAM WPARAM, LPARAM LPARAM)
{
SOCKET s = wParam;
if (Wsagetselecterror (LParam))
{
:: Closesocket (M_socket);
M_socket = Invalid_socket;
return 0;
}
Switch (wsagetselectevent (lParam))
{
Case Fd_read:
{
MessageBox ("Client:read");
Char sztext[1024]={0};
:: Recv (S, sztext, 1024, 0);
Addstringtolist (CString (sztext) + "\ r \ n");
}
Break
Case Fd_connect:
{
MessageBox ("Client:connect");
GetDlgItem (Idc_connect)->setwindowtexta ("Disconnected");
GetDlgItem (IDC_ADDR)->enablewindow (FALSE);
GetDlgItem (Idc_port)->enablewindow (FALSE);
GetDlgItem (Idc_text)->enablewindow (TRUE);
GetDlgItem (idc_send)->enablewindow (TRUE);
M_bar. SetText ("Already connected to server", 0, 0);
}
Break
Case Fd_close:
{
MessageBox ("Client:close");
OnConnect ();
}
Break
}
return 0;
}
BOOL Cmaindialog::connect (LPCTSTR pszremoteaddr, U_short nport)
{
Creating sockets
M_socket =:: Socket (af_inet, sock_stream, ipproto_tcp);
if (Invalid_socket = = M_socket)
{
return FALSE;
}
:: WSAAsyncSelect (M_socket, M_hwnd, Wm_socket, fd_read| fd_write| Fd_connect| Fd_close);
ULONG uaddr =:: inet_addr (PSZREMOTEADDR);
if (uaddr = = Inaddr_none)
{
is not an IP address, it is considered a host name
Get IP from host name
hostent* Phost =:: gethostbyname (PSZREMOTEADDR);
if (Phost = NULL)
{
:: Closesocket (M_socket);
M_socket = Invalid_socket;
return FALSE;
}
Uaddr = ((struct in_addr*) * (phost->h_addr_list))->s_addr;
}
Fill in Server information
SOCKADDR_IN remote;
remote.sin_family = af_inet;
Remote.sin_addr. S_un. S_ADDR = uaddr;
Remote.sin_port =:: Htons (Nport);
Connection
:: Connect (M_socket, (sockaddr*) &remote, sizeof (SOCKADDR));
return TRUE;
}
void Cmaindialog::onconnect ()
{
if (Invalid_socket = = m_socket)//Connect server
{
CString straddr;
GetDlgItem (IDC_ADDR)->getwindowtext (STRADDR);
if (Straddr.isempty ())
{
MessageBox ("The Servers IP is empty");
Return
}
CString Strport;
GetDlgItem (Idc_port)->getwindowtexta (Strport);
int nport = atoi (Strport);
if (Nport < 1 | | nport > 65535)
{
MessageBox ("Port error");
Return
}
if (Connect (straddr, nport) = = FALSE)
{
MessageBox ("Connect to servers error ...");
Return
}
Setting up the user interface
GetDlgItem (Idc_connect)->setwindowtext ("cancellation");
M_bar. SetText ("Connecting ...", 0, 0);
}
else//Disconnect Server
{
:: Closesocket (M_socket);
M_socket = Invalid_socket;
Setting up the user interface
GetDlgItem (Idc_connect)->setwindowtexta ("Connecting server");
M_bar. SetText ("Free", 0, 0);
GetDlgItem (IDC_ADDR)->enablewindow (TRUE);
GetDlgItem (Idc_port)->enablewindow (TRUE);
GetDlgItem (idc_send)->enablewindow (FALSE);
GetDlgItem (Idc_text)->enablewindow (FALSE);
}
This->connect (SZADDR,)
}
void Cmaindialog::onsend ()
{
CString strsendcontent;
GetDlgItem (Idc_text)->getwindowtexta (strsendcontent);
:: Send (M_socket, strsendcontent, Strsendcontent.getlength (), 0);
GetDlgItem (Idc_text)->setwindowtexta ("");
}
TCPClient.h header files are as follows:
Copy Code code as follows:
#include <afxwin.h>
#include <afxext.h>//cstatusbar
#include <WinSock2.h>
#include <afxcmn.h>
#pragma comment (lib, "Ws2_32.lib")
#define Max_socket 56//MAX Customer Volume
Class Cmyapp:public CWINAPP
{
Public
BOOL InitInstance ();
};
Cmaindialog
Class Cmaindialog:public CDialog
{
Public
Cmaindialog (cwnd* pparentwnd=null);
Protected
Virtual BOOL OnInitDialog ();
virtual void OnCancel ();
Turn on or off a service
afx_msg void OnStart ();
afx_msg void OnSend ();
afx_msg Long Onsocket (WPARAM WPARAM, LPARAM LPARAM);
void OnConnect ();
BOOL Connect (LPCTSTR pszremoteaddr, u_short nport);
SOCKET M_socket;
Control
CStatusBarCtrl M_bar;
CEdit M_edit_text;
void Addstringtolist (CString strText);
BOOL createandlisten (int nport);
Add a customer to the Customer connection list
BOOL addclient (SOCKET s);
Remove a customer from the Customer connection list
void Removeclient (SOCKET s);
Close all connections
void Closeallsocket ();
Declare_message_map ()
};
I hope this article will help you with the C + + program design.