Quickly implement network programming CasyncSocket using MFC

zhaozj2021-02-08  256

Quickly implement network programming using MFC

Fuzhou University Wang Jun

---- With the in-depth of computer network, computer network programming has become increasingly important in programming. Due to the superiority of the C language on the underlying operation, many articles have been introduced to use VC for Socket programming methods. However, since it is directly using dynamic connection wsock32.dll, it is more cumbersome. In fact, the VC MFC class library provides a socket class such as CasyncSocket, which is very convenient to implement Socket programming.

---- This article will use an ECHO routine to introduce the usage of the CasyncSocket class.

---- One. Client

---- 1. Create a Dialog Based project: CSockClient.

---- 2. Design dialog

---- Remove the OK and CANCLE two buttons, add ID_connect (connection), ID_send button, add the ListBox control IDC_LISTMSG and Edit control idc_editmsg, and press the table to add variables for CCSockClientDlg class in ClassWizard .

Control ID Type MEMBER

IDC_EDITMSG CEDIT M_MSG

IDC_LISTMSG CLISTBOX M_MSGS

---- 3. The CasyncSocket class processes the MFC message with the Docallback function. When a network event occurs, the DOCALLBACK function is called on Network Event Type: fd_read, fd_write, fd_accept, fd_connect, respectively calls OnReceive, OnSend, OnAccept, ONCONNECT functions. Since the MFC defines these event handlers as a virtual function, you have to generate a new C class to overrunate these functions, the practice is as follows:

---- Inheriting the CasyncSocket class in a public manner, generating new class mysock;

---- Add virtual functions for MySOCK classes onreceive, onConnect, Onsend

---- 4. Add the following code in MySock.ccp

#include "csockclient.h"

#include "csockclientdlg.h"

---- 5. Add the following code to mysock.h

PUBLIC:

BOOL M_BCONNECTED; / / Whether

UINT M_NLENGTH; // Message Length

Char m_szbuffer [4096]; // message buffer

---- 6. Heavy load function in mysock.ccp

Mysock :: mysock ()

{

m_nlength = 0;

Memset (m_szbuffer, 0, sizeof (m_szbuffer);

m_bconnected = false;

}

Mysock :: ~ mysock ()

{

// Close the 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 obtain the dialog pointer

CCSockClientApp * PAPP = (ccsockclientapp *) AFXGetApp ();

CcSockClientdlg * PDLG = (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;

CCSockClientApp * PAPP = (ccsockclientapp *) AFXGetApp ();

CcSockClientdlg * PDLG = (ccsockclientdlg *) PAPP-> m_pmainwnd;

Memcpy (M_SZBuffer, "Connected to", 13);

Strncat (m_szbuffer, pdlg-> m_szserveradr,

SizeOf (PDLG-> M_SZSERVERVERADR);

PDLG-> m_msgs.insertstring (0, m_szbuffer);

Asyncselect (fd_read); Select a "read" network event, ready to receive

}

CasyncSocket :: onConnect (NERRORCODE);

}

---- 7. New dialog IDD_ADDR, used to enter IP addresses and port; generate new class Caddrdlg. Add two edit controls: IDC_ADDR, IDC_Port Press the table to add variables for the Caddrdlg class in ClassWizard.

Control ID Type MEMBER

IDC_ADDR CSTRING M_ADDR

IDC_PORT INT M_PORT

---- 8. Add code in csockclientdlg.ccp

#include "addrdlg.h"

protected:

INT TRYCOUNT;

Mysock m_clientsocket;

Uint m_szport;

PUBLIC:

Char m_szserveradr [256];

---- 9. Double-click the "Connection" button in the IDD_CSockClient_Dialog dialog box, 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, try to connect once every 1 second until it is connected or trycount> 10Settimer (1, 1000, null);

Trycount = 0;

}

}

---- 10. Add 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, 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, add the following code

Void ccsockclientdlg :: Onexit ()

{

// Close Socket

m_clientsocket.shutdown (2);

// Close dialog

Enddialog (0);

}

----

12. Run this project, enter the host name or IP when the connection is connected, and the CasyncSocket class will automatically process.

----

two. Server

----

Server end programming is similar to the Client side, which mainly introduces his Listen and Accept functions.

----

1. Create a CNEWSocket class, overreeNCSocket classes, onreceive, onsend functions, how to display and send information about information, can refer to the Client program. In this example, the method of receiving the information is not sent back to the original situation is used to implement the ECHO function, and the code is as follows.

CNewsocket :: OnReceive (int NerrorCode)

{

m_nlength = Receive (m_szbuffer, sizeof (m_szbuffer), 0);

// Direct forwarding message

Asyncselect (fd_write);

}

CNewsocket :: Onsed (int Nerror) {

Send (m_szbuffer, m_nlength, 0);

}

----

2. Create a CMYSERVERSOCKET class, the onaccept function code for the overload CasyncSocket class is as follows

----

Declaring variables in MyServersocket.h

PUBLIC ::

CNewsocket * m_psocket;

Void CMYSERVERSOCKET :: onaccept (int NerrorCode)

{

// So the connection request, call the accept function

CNewsocket * psocket = new cnewsocket ();

IF (ACCEPT (* psocket))

{

PSocket-> asyncselect (fd_read);

m_psocket = psocket;

}

Else

DELETE PSOCKET;

}

----

3. Add a "listening" button to the dialog, add the following code

----

Declaring variables in csockserverdlg.ccp

PUBLIC:

CMYSERVERSOCKET M_SRVRSOCKET;

Void ccsockServerdlg :: online ()

{

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" success, waiting for the 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. The current program can only implement the ECHO function, forward the information, if you can't move, if you can use the CNEWSocket * psocket = new cnewsocket (); get the Socket pointer to a CLIST or an array, like the Client side, Read and write all connections. ----

three. to sum up

----

The CasyncSocket class provides us with Socket to provide great convenience. Establishing a Socket's WSAStartup process and Bind procedures are simplified to become create processes, IP address type conversions, host names, and IP address translations. Many complex variable types are simplified into strings and integers, especially asynchronous features of CasyncSocket classes. Can fully replace the cumbersome thread operation. The MFC provides a large number of libraries, and if we can use them flexibly, we will greatly improve the efficiency of programming.

转载请注明原文地址:https://www.9cbs.com/read-1690.html

New Post(0)