Http://www.cppblog.com/changshoumeng/archive/2010/05/14/115413.html
3.8 one using CSocket Class of network traffic instances
This example uses CSocket The programming model establishes a simple instance of a chat program. Note that the Windows sockets check box is selected when you build the project .
3.8.1 server-side application design (Serverdemo)
1 ) Interface
The properties of each control are as follows
|
control type |
Control ID |
Caption Properties |
Control variables |
Variable type |
|
list box |
Idc_log |
No |
M_logctrl |
CListBox |
|
edit box |
Idc_message |
No |
M_msgctrl |
CEdit |
|
Button |
Idc_send |
Send |
M_sendctrl |
CButton |
|
static controls |
Idc_static |
Recording |
No |
No |
|
static controls |
Idc_static |
Outgoing messages |
No |
No |
The list box control Idc_log Property "Sort" value is false, and the property "horizontal Scroll" value is true.
Button Idc_send Property Disable value is true.
2) define the derived classes Cservsocket and Crecvsocket of the CSocket class.
From the CSocket programming model, it is known that the server side requires two sockets, one to listen for connection requests and one to establish a connection to the socket that requests the connection. Therefore, add two CSocket derived classes to the program: Sservsocket and Crecvsocket, which work closely with the dialog class to accomplish the functions required by the program.
3) Establish the association of the socket with the dialog box class
In the program, the dialog class uses the socket class, and the socket class responds to certain messages, such as in functions OnAccept, OnReceive, and also changes some control states of the dialog box to reflect the occurrence of these things to the user.
There are two classes that use each other, define the socket class object as a member variable of the dialog class, and define the dialog class as a member variable in the Socket class. How do you implement such a usage? It is obviously not feasible to include the declaration of the socket header file in the header file of the dialog box, and then add the declaration of the header file of the dialog box to the socket class header file.
The specific approach should be as follows:
First, add the declaration of the Socket class header file to ServerDemoDlg.h, and add the following statement after the statement #pragma once:
#include "ServSocket.h"
#include "RecvSocket.h"
Then add two public member variables for the Cserverdemodlg class in the file, with the following statement:
Cservsocket *servsock;
Crecvsocket *recvsock;
This allows the socket class to be used in the dialog box class.
Continue to include dialog class information in the socket class.
First, at the beginning of the ServSocket.h file, add the following statement after the statement #pragma once:
Class Cserverdemodlg;
Then, add a public member variable and a constructor to the Cservsocket class in the file:
Cservsocket (Cserverdemodlg *dlg);
Cserverdemodlg *m_dlg;
Then add the implementation of the new constructor to the ServSocket.cpp file and add a precompiled declaration about the ServerDemoDlg.h file, as follows:
#include "ServerDemoDlg.h"
Cservsocket::cservsocket (Cserverdemodlg *dlg)
{
M_dlg=dlg;
}
In this way, dialog boxes can also be used in the socket class through member variables.
Use the same method to set the Crecvsocket class so that it can also use the dialog box through member variables.
4) The ability to add serialized read-write information to sockets. In two sockets on the server side, only the crecvsocket socket is really connected to the client socket, sending and receiving data, so we only add the serialization read-write information function to the class. Add three public member variables for class Crecvsocket in the RecvSocket.h file.
CSocketFile *m_file;
CArchive *m_arin;
CArchive *m_arout;
5) Initialize the socket in the dialog box and listen for the connection request. Add the following code to the OnInitDialog function:
TODO: Add additional initialization code here
if (servsock=new cservsocket (This))
{
if (Servsock->create (9547))
{
M_logctrl.addstring ("Waiting for Connection ...");
Servsock->listen ();
}
Else
{
M_logctrl.addstring ("Initialization failed, please restart the program!") ");
Delete Servsock;
}
}
Else
{
M_logctrl.addstring ("Initialization failed, please restart the program!") ");
}
The code above primarily creates and initializes the servsock socket and starts listening for connection requests.
6) Accept the connection request. Because the Servsock object of the Cservsocket class is listening for the connection request, the connection request is accepted by the class.
First, add the following statement to the ServSocket.h file:
#iinclude "RecvSocket.h"
Then, overload the OnAccept function of the class and add the following code to the function:
Crecvsocket *tempsock;
if (tempsock=new crecvsocket (THIS->M_DLG))
{
if (Accept (*tempsock))
{
Tempsock->m_file =new CSocketFile (tempsock);
Tempsock->m_arin =new CArchive (Tempsock->m_file, carchive::load);
Tempsock->m_arout =new CArchive (Tempsock->m_file, Carchive::store);
M_dlg->recvsock =tempsock;
Tempsock=null;
M_dlg->m_logctrl. AddString ("The connection is successful, you can start delivering messages");
M_dlg->m_sendctrl.enablewindow (TRUE);
}
Else
{
M_dlg->m_logctrl. AddString ("The client's current connection attempt failed");
Delete Tempsock;
}
}
Else
{
M_dlg->m_logctrl. AddString ("Connection socket initialization failed");
}
The code above first calls the Accept function to take a connection request, then creates a socket of type crecvsocket for the connection and associates the CArchive object with the socket, enabling it to serialize the transmission of information. Finally, a good socket is passed back to the dialog object for its use. In this way, the member variable recvsock socket of the dialog object establishes an information channel between the client sockets and the information is passed between two sockets.
7) Receive information, when the connection is established successfully, when the information arrives at the server side, it will raise the onreceive function of the Recvsock socket object, so the OnReceive function of the Crecvsocket class needs to be overloaded. Add the following code:
CString str;
(*m_arin) >>str;
M_dlg->m_logctrl. AddString ("The information sent by the other party is as follows:");
M_dlg->m_logctrl. AddString (str);
M_dlg->m_logctrl. SetCurSel (M_dlg->m_logctrl. GetCount ()-1);
8) Send the message. Add the event handler Onbnclickedsend () to the "Send" button of the dialog box, with the following code:
void Cserverdemodlg::onbnclickedsend ()
{
TODO: Add control notification Handler code here
CString str;
M_msgctrl.getwindowtext (str);
if (str. GetLength () ==0)
AfxMessageBox ("Empty information, so do not issue");
Else
{
M_logctrl.addstring ("The message you sent is as follows:");
M_logctrl.addstring (str);
M_logctrl.setcursel (M_logctrl.getcount ()-1);
* (recvsock->m_arout) <<str;
Recvsock->m_arout->flush ();
}
}
3.8.2 client application Design ( project name Clientdemo)
1 ) Interface
The properties of each control are as follows
|
control type |
Control ID |
Caption Properties |
Control variables |
Variable type |
|
list box |
Idc_log |
No |
M_logctrl |
CListBox |
|
edit box |
Idc_message |
No |
M_msgctrl |
CEdit |
|
Button |
Idc_send |
Send |
M_sendctrl |
CButton |
|
static controls |
Idc_static |
Recording |
No |
No |
|
static controls |
Idc_static |
Outgoing messages |
No |
No |
The list box control Idc_log Property "Sort" value is false, and the property "horizontal Scroll" value is true.
Button Idc_send Property Disable value is true.
2) Create a socket class (derived from the CSocket class). The client only needs a socket, named Cclientsocket.
3) Establish the Association of the dialog class with the socket class.
First, at the beginning of the ClientDemoDlg.h file, add the following statement after the statement #pragma once:
#include "ClientSocket.h"
Then, in the file, add a public member variable for the Cclientdemodlg class, with the following statement:
Cclientsocket *clientsock;
Next, at the beginning of the ClientSocket.h file, add the following statement after the statement #pragma once:
Class Cclientdemodlg;
Then, in the file, add a public member variable and a constructor for the Cclientsocket class, with the following statement:
Cclientsocket (Cclientdemodlg *dlg);
Cclientdemodlg *m_dlg;
Next, add the implementation code for the new constructor in the ClientSocket.cpp file, and add a precompiled declaration about the CClientDemoDlg.h file, with the following code:
#include "ClientDemoDlg.h"
Cclientsocket::cclientsocket (Cclientdemodlg *dlg)
{
M_dlg=dlg;
}
This completes the connection between the dialog box and the socket.
4) The ability to add serialized read-write information to sockets. In the ClientSocket.h file, add three public member variables for class Cclientsocket, with the following code:
CSocketFile *m_file;
CArchive *m_arin;
CArchive *m_arout;
5) Initialize the socket and establish the connection in the dialog box
Add the following code to the OnInitDialog function of the dialog class
TODO: Add additional initialization code here
m_logctrl.addstring ("Connecting ...");
if (clientsock=new cclientsocket (This))
{
if (Clientsock->create ())
{
if (Clientsock->connect ("localhost", 9547))
{
Clientsock->m_file =new CSocketFile (clientsock);
Clientsock->m_arin =new CArchive (Clientsock->m_file, carchive::load);
Clientsock->m_arout =new CArchive (Clientsock->m_file,carchive::store);
M_logctrl.addstring ("The connection is successful, you can start delivering messages");
M_sendctrl.enablewindow (TRUE);
}
Else
{
M_logctrl.addstring ("Connection not successful");
Delete Clientsock;
}
}
Else
{
M_logctrl.addstring ("Initialization failed, please restart program");
Delete Clientsock;
}
}
Else
{
M_logctrl.addstring ("Initialization failed, please restart program");
}
6) receive the message. When the message arrives, the onreceive message of the socket is raised, so the onreceive function of the Cclientsocket class is overloaded, where the code is added as follows
TODO: Add private code here and/or call base class
CString str;
M_dlg->m_logctrl. AddString ("The other party sent a message as follows:");
*m_arin>>str;
M_dlg->m_logctrl. AddString (str);
M_dlg->m_logctrl. SetCurSel (M_dlg->m_logctrl. GetCount ()-1);
7) Send the message. Add the event handler Onbnclickedsend () to the "Send" button of the dialog box, with the following code:
void Cclientdemodlg::onbnclickedsend ()
{
TODO: Add control notification Handler code here
CString str;
M_msgctrl.getwindowtext (str);
if (str. GetLength () ==0)
AfxMessageBox ("Empty information, so do not issue");
Else
{
M_logctrl.addstring ("You send the message as follows:");
M_logctrl.addstring (str);
M_logctrl.setcursel (M_logctrl.getcount ()-1);
* (clientsock->m_arout) <<str;
Clientsock->m_arout->flush ();
}
}
# Re: A network communication instance server program that uses the CSocket class is compiled with your steps.
if (servsock=new cservsocket (This))
{
if (Servsock->create (9547))
{
M_logctrl.addstring ("Waiting for Connection ...");
Servsock->listen ();
}
Else
{
M_logctrl.addstring ("Initialization failed, please restart the program!") ");
Delete Servsock;
}
}
Create failed, always jump to else inside go, excuse me what is the reason ah? If convenient, you can send the source program my mailbox number, my own research! [Email protected] Li Yu comment on 2012-02-14 15:05 reply more comments # Re: A network communication instance that uses the CSocket class joins
if (! AfxSocketInit ())
{
AfxMessageBox (idp_sockets_init_failed);
return FALSE;
}
In the resource header file, add
#define IDP_SOCKETS_INIT_FAILED 104
Also include in the string table
ID idp_sockets_init_failed
Caption Windows Communication port initialization failed.
A network communication instance using the CSocket class