Tagged with: C + + MFC
VC + + MFC class Library provides casyncsocket such a socket class, with him to achieve
Socket programming, is very convenient.
This article uses an echo routine to describe the use of the CAsyncSocket class.
A Client
1. Create a Dialog based project: Csockclient.
2. Design dialog box
Remove the OK and cancle two buttons, add id_connect (Connect), Id_send (send),
Id_exit (Close) button, add ListBox control idc_listmsg and edit Control Idc_editmsg,
and add a variable to the Ccsockclientdlg class in ClassWizard by the following table.
3. The CAsyncSocket class uses the DoCallback function to process MFC messages, and when a network event occurs,
DoCallback functions by Network Event Type: Fd_read, Fd_write, Fd_accept, Fd_connec
ControlID Type Member
Idc_editmsg CEdit m_msg
Idc_listms CListBox M_msgs
Call the OnReceive, OnSend, onaccept, and OnConnect functions, respectively. Because MFC puts these events
The handler function is defined as a virtual function, so a new C + + class is generated to overload the functions as follows:
Inherit the CAsyncSocket class as public and generate a new class Mysock;
Add virtual functions onreceive, OnConnect, OnSend for the Mysock class
4. Add the following code in the MYSOCK.CCP
#include "CSockClient.h"
#include "CSockClientDlg.h"
5. Add the following code in the MySock.h
Public
BOOL m_bconnected; Whether to connect
UINT m_nlength; Message length
Char m_szbuffer[4096]; Message buffers
6. Overloading each function in MYSOCK.CCP
Mysock::mysock ()
{
m_nlength=0;
memset (m_szbuffer,0,sizeof (M_szbuffer));
M_bconnected=false;
}
Mysock::~mysock ()
{
Close socket
if (M_hsocket!=invalid_socket)
Close ();
}
void mysock::onreceive (int nerrorcode)
{
M_nlength=receive (M_szbuffer,sizeof (M_szbuffer), 0);
The following two lines of code are used to get the dialog pointer
Ccsockclientapppapp= (Ccsockclientapp) AfxGetApp ();
Ccsockclientdlgpdlg= (Ccsockclientdlg) papp->m_pMainWnd;
pdlg->m_msgs. Insertstring (0,m_szbuffer);
memset (m_szbuffer,0,sizeof (M_szbuffer));
Casyncsocket::onreceive (Nerrorcode);
}
void mysock::onsend (int nerrorcode)
{
Send (m_szbuffer,m_nlength,0);
m_nlength=0;
memset (m_szbuffer,0,sizeof (M_szbuffer));
Continue to draw a "read" network event to receive the server message
AsyncSelect (Fd_read);
Casyncsocket::onsend (Nerrorcode);
}
void Mysock::onconnect (int nerrorcode)
{
if (nerrorcode==0)
{
M_bconnected=true;
Ccsockclientapppapp= (Ccsockclientapp) AfxGetApp ();
Ccsockclientdlgpdlg= (Ccsockclientdlg) papp->m_pMainWnd;
memcpy (M_szbuffer, "Connected to", 13);
Strncat (m_szbuffer,pdlg->m_szserveradr,
sizeof (pdlg->m_szserveradr));
pdlg->m_msgs. Insertstring (0,m_szbuffer);
AsyncSelect (Fd_read); Draw a "read" network event to prepare to receive
}
Casyncsocket::onconnect (Nerrorcode);
}
7. New dialog box idd_addr, which is used to enter the IP address and Port, and to generate a new class Caddrdlg. Increase
Two edit controls: Idc_addr, Idc_port Press the table in ClassWizard to add the Caddrdlg class
Add variable.
Control ID Type Member
Idc_addr CString m_addr
Idc_port int M_port
8. Add code to CSOCKCLIENTDLG.CCP
#include "AddrDlg.h"
Protected
int trycount;
Mysock M_clientsocket;
UINT M_szport;
Public
Char m_szserveradr[256];
9. Double-click the Connect button in the Idd_csockclient_dialog dialog box to add the following code
void Ccsockclientdlg::onconnect ()
{
M_clientsocket.shutdown (2);
M_clientsocket.m_hsocket=invalid_socket;
M_clientsocket.m_bconnected=false;
Caddrdlg M_dlg;
Default Port 1088
m_dlg.m_port=1088;
if (M_dlg.domodal () ==idok &&!m_dlg.m_addr.isempty ())
{
memcpy (m_szserveradr,m_dlg.m_addr,sizeof (M_SZSERVERADR));
M_szport=m_dlg.m_port;
Establish a timer that attempts to connect once every 1 seconds until connected or trycount>10
SetTimer (1,1000,null);
trycount=0;
}
}
10. Add a Windows message wm_timer response function OnTimer
void Ccsockclientdlg::ontimer (UINT nidevent)
{
if (M_clientsocket.m_hsocket==invalid_socket)
{
BOOL bflag=m_clientsocket.create (0,sock_stream,fd_connect);
if (!bflag)
{
AfxMessageBox ("Socket error!");
M_clientsocket.close ();
PostQuitMessage (0);
Return
}
}
M_clientsocket.connect (M_szserveradr,m_szport);
trycount++;
if (Trycount >=10 | | m_clientsocket.m_bconnected)
{
KillTimer (1);
if (Trycount >=10)
AfxMessageBox ("Connect failed!");
Return
}
Cdialog::ontimer (nidevent);
}
11. Double-click the Send button in the Idd_csockclient_dialog dialog box to add the following code
void Ccsockclientdlg::onsend ()
{
if (m_clientsocket.m_bconnected)
{
M_clientsocket.m_nlength=m_msg. GetWindowText
(M_clientsocket.m_szbuffer, sizeof (M_clientsocket.m_szbuffer));
M_clientsocket.asyncselect (Fd_write);
M_msg. SetWindowText ("");
}
}
12. Double-click the Close button in the Idd_csockclient_dialog dialog box to add the following code
void Ccsockclientdlg::onexit ()
{
Close socket
M_clientsocket.shutdown (2);
Close the dialog box
EndDialog (0);
}
12. When you run this project, you can enter the host name or IP when you connect, and the CAsyncSocket class will automatically process.
Two Service side
Server-side programming is similar to the client side, and the following is a description of his listen and accept functions
1. Create a Cnewsocket class that overloads the OnReceive, OnSend functions of the CAsyncSocket class,
How to display and send the information can refer to the client program. In this case, the information received will be intact
A way to implement the Echo function, the code is as follows
Cnewsocket:: onreceive (int nerrorcode)
{
M_nlength=receive (M_szbuffer, sizeof (M_szbuffer), 0);
Forward messages directly
AsyncSelect (Fd_write);
}
Cnewsocket:: onsend (int nerrorcode)
{
Send (M_szbuffer, m_nlength, 0);
}
2. Create a Cmyserversocket class that overloads the OnAccept function code of the CAsyncSocket class
As follows
Declaring variables in MyServerSocket.h
Public::
CnewsocketM_psocket;
void Cmyserversocket:: onaccept (int nerrorcode)
{
To hear the connection request, call the Accept function
CnewsocketPsocket = new Cnewsocket ();
if (Accept (Psocket))
{
psocket->asyncselect (Fd_read);
M_psocket=psocket;
}
Else
Delete Psocket;
}
3. Add a Listen button to the dialog box and add the following code
Declaring variables in CsockServerDlg.h
Public
Cmyserversocket M_srvrsocket;
void Ccsockserverdlg:: Onlisten ()
{
if (M_srvrsocket.m_hsocket==invalid_socket)
{
BOOL bflag=m_srvrsocket.create
(Userport, Sock_stream, fd_accept);
if (! Bflag)
{
AfxMessageBox ("Socket error! ”) ;
M_srvrsocket.close ();
PostQuitMessage (0);
Return;
}
}
"Listening" succeeds, waiting for connection request
if (! M_srvrsocket. Listen (1))
{
int nerrorcode = M_srvrsocket.getlasterror ();
if (nerror! =wsaewouldblock)
{
AfxMessageBox ("Socket error! ”) ;
M_srvrsocket.close ();
PostQuitMessage (0);
Return;
}
}
}
4. At present, the program can only implement the Echo function, the information is forwarded intact, if you can accept the
CnewsocketPsocket = new Cnewsocket (); The resulting socket pointer is stored in a
CList or an array, like the client side, reads and writes all connections.
Three Summarize
The CAsyncSocket class provides great convenience for us to use the socket. Set up a socket WSAStartup
Process and bind processes are simplified into the Create process, IP address type conversions, hostname and IP address forwarding
Many of the complex variable types are simplified into string and integer operations, especially
The asynchronous nature of the CAsyncSocket class can completely replace tedious threading operations. MFC provides a large number of
Class Library, if we can use them flexibly, it will greatly improve the efficiency of programming.
"MFC Network Programming" learning Diary 2