"MFC Network Programming" learning Diary 3

Source: Internet
Author: User
Tags sendmsg serialization

A UDP -based network communication program:
The entire example has two programs, one sends the data, and the other program receives the data, completing the drawing work
For
This program runs as follows:


First, the sender program
The Data Sender program (FASON) is established first. Send a total of four data: The x-coordinate of the center, Y of the center
coordinates, circle radius R, circle color. Its implementation is mainly as follows:
void Cfasondlg::onsend ()
{
UpdateData (TRUE);
CString m_getstring;
This->m_cob.getlbtext (M_cob.getcursel (), m_getstring);
if (m_getstring==_t ("Red"))
Yuan1.color=1;
if (m_getstring==_t ("Green"))
yuan1.color=2;
if (m_getstring==_t ("Blue"))
yuan1.color=3;
yuan1.x=m_x;
yuan1.y=m_y;
Yuan1.r=m_r;
p=&yuan1;
CSocket M_hsocket;
M_hsocket.create (2330,sock_dgram);
M_hsocket.sendto (P,sizeof (yuan1), 3550, "127.0.0.1");//send with struct.
m_x=0;
m_y=0;
m_r=0;
M_hsocket.close ();
UpdateData (FALSE);
}
One technique for sending data is that all data is sent in a struct, without a
Send. However, you cannot include data types such as CString that can be long in a struct.
Second, the receiving procedure
Let's take a look at the program that receives the data end (Jieshou). as follows: void
cdasocket::onreceive (int nerrorcode)
{
Char buff[256];
int ret=0;
Ret=receive (buff,256);
if (ret==error)
{
TRACE ("error!");
}
Else
M_pdoc->presscessding (Buff);
Casyncsocket::onreceive (Nerrorcode);
}
Third, data processing and display
When we design the program, the data is usually processed in the document and the work is done in the view. When the entire program
Small, this does not feel good, but the whole program is larger, the program will be more clear, easy
Good reading. Therefore, must always develop good design habits. The data is processed in the document as follows:
void Cjieshoudoc::P resscessding (char* lbuff)
{
buff= (struct yuan*) Lbuff;
p.x=buff->x;
p.y=buff->y;
p.r=buff->r;
p.color=buff->color;
UpdateAllViews (NULL);
}
The display in the view is as follows:
void Cjieshouview::ondraw (cdc* pDC)
{
cjieshoudoc* PDoc = GetDocument ();
Assert_valid (PDOC);
x=pdoc->p.x;
y=pdoc->p.y;
r=pdoc->p.r;
if (pdoc->p.color==1)
Pdc->selectobject (New CBrush (RGB (255,0,0)));
if (pdoc->p.color==2)
Pdc->selectobject (New CBrush (RGB (0,255,0)));
if (pdoc->p.color==3)
Pdc->selectobject (New CBrush (RGB (0,0,255)));
Pdc->ellipse (X-R,Y-R,X+R,Y+R);
}
V. Re-discussion on the basis ofWinSocketImplementation of network communication:
In VC + +, MFC programming supports two programming modes of network communication using WindowsSockets,
Both of these modes are the CSocket classes that are used with the CAsyncSocket class and derived from CAsyncSocket.
The CAsyncSocket class encapsulates the WINDOWSSOCKETSAPI function, which provides a lower layer of the Windows
Sockets dialog interface, generally suitable for a considerable level of network programming based on the use of the user can easily
The underlying network event notification and information callback control operations.
CSocket is derived from CAsyncSocket, which inherits some common, easy-to-understand Windows in the parent class
Sockets API functions and some API functions or members that are more difficult to control in the CAsyncSocket
The function is processed by Mfccarchive object, which makes the network transmission
As with the MFC Document serialization Protocol (serialization protocol), simple and easy to use. It also supports
With the modular background information processing, it solves the more difficult multithreading in CAsyncSocket.
SerializationExplain
To create a class with serialization capability
Class Cmessagechar:public CObject
{
Public
Cmessagechar ();
Virtual ~cmessagechar () {};
Overloaded serialization functions for serialization of messages
virtual void Serialize (carchive& ar);
CString M_strtext;
};
Cmessagechar::cmessagechar ()
{m_strtext = "xnbbbb";}
void Cmessagechar::serialize (carchive& ar)
{
if (AR. IsStoring ())
{ar << m_strtext;}
Else
{ar >> m_strtext;}
}
Write two examples of serialization
void Cserialtestdlg::onbutwrite ()
{
CFile file;
Char buf[512];
File. Open ("E:\\demo.txt", Cfile::modecreate | Cfile::modewrite);
CArchive asessionout (&AMP;FILE,CARCHIVE::STORE,512,BUF);
Cmessagechar AA;
Aa. Serialize (asessionout);
Asessionout.close ();
File. Close ();
}
void Cserialtestdlg::onbutread ()
{
CFile file;
Char buf[512];
File. Open ("E:\\demo.txt", Cfile::moderead);
CArchive Asessionin (&AMP;FILE,CARCHIVE::LOAD,512,BUF);
Cmessagechar AA;
Aa. Serialize (Asessionin);
Asessionin.close ();
File. Close ();
}
SocketThe establishment and use of operations
As a server, you need a socket that is dedicated to receiving, so that you can receive it from customers at any time.
Information, the CSocket class's listen itself supports multithreading, so it does not have to open new threads for it. Built
The steps for Windows Sockets are shown in table 1.
ServerSocketThe establishment and use of
The socket global variable is known in the server application and is left in a listening state to wait for the customer
Terminal to establish a connection with:
Clisteningsocket M_psocket;
M_psocket = new Clisteningsocket (this);
if (M_psocket->create (dialog.m_nport+700))
{if (M_psocket->listen ())
return TRUE;
}
Call the document class to receive a new customer's processing when the client's active connection is received or when the data is received
Number:
void clisteningsocket::onaccept (int nerrorcode)
{
Csocket::onaccept (Nerrorcode);
M_pdoc->processpendingaccept ();
Call the document class member function to generate a new conversation thread
}
Server socket network data sending and receiving operations:
void Cclientsocket::sendmsg (Cmsg pMsg)
{
if (m_parchiveout! = NULL)
{pmsg->serialize (m_parchiveout);
Calling functions that customize information classes by Protocol (CMSG)
M_parchiveout->flush ();
Serialize online information sending operation
}
}
void Cclientsocket::receivemsg (Cmsg pMsg)
{
Pmsg->serialize (M_parchivein);
}//Invoke functions that customize information classes by Protocol (CMSG)
Serialize on-line information receiving operation
Client Building connection and communication implementation
New customers connect to the server side:
BOOL Cchatdoc::connectsocket (LPCTSTR lpszhandle,
LPCTSTR lpszaddress, UINT nport)
{m_strhandle = Lpszhandle;
M_psocket = new Cchatsocket (this);
if (!m_psocket->create ())
{...} Create new socket failure handling
while (!m_psocket->connect (lpszaddress, Nport + 700))
{...} Processing after a failed connection to the server
M_pfile = new CSocketFile (m_psocket);
M_parchivein = new CArchive (m_pfile,carchive::load);
M_parchiveout = new CArchive (M_pfile,carchive::store);
Establishing a communication Flow object
return TRUE;
}
* Client reads the information from the stream into the Web:
void cchatdoc::receivemsg ()
{cmsg msg;
TRY {msg. Serialize (M_parchivein);
//Call function for custom information class (CMSG) by Protocol
while (!msg.m_msglist.isempty ())//serialize for online information receive operation
{...
CATCH (CFileException, E) {...} End-catch//Error handling
if (msg.m_bclose)
{...}//Close connection Aftercare
}
* Client sends information online via stream:
void Cchatdoc::sendmsg ( cstring& strtext,int index,int i)
{
if (m_parchiveout! = NULL)
{cmsg msg;
Msg=assemblemsg (Index,i);
//assembly information
try {msg->serialize (m_parchiveout);
Call the function
M_parchiveout->flush () that defines the information class by Protocol (CMSG);
//serialize for online information send operation
}
catch (CFileException, E)
{...}//error handling
}
}
table 1


/span>



Vi. in-depthCSocketProgramming blocking and non-blocking modes
Here the concept of blocking and non-blocking applies only to the Server-side socket program. The socket is a
socket, which differs from the socket, note the case of the first letter.
Client-to-server communication is simple: the server socket is responsible for listening, answering, receiving and
sending messages, while the client socket is just the connection, answer, receive, and send messages. In addition, if you
do not know how to write Client/server network programs using the CSocket class, please check the
inquiry (see: Reference books and online Help).
Before this, it is necessary to tell first: Network transport service provider, Ws2_32.dll, socket event
and Socket window.

1, concept
network transport service provider (Network transport service process) , socket event, Socket Window
The network transport service provider (transport service provider) exists in the form of a DLL
that is svchost.ex by the service process when the Windows operating system starts E load. When the socket
is created, call the API function socket (in Ws2_32.dll), the socket function will pass
Three parameters: Address family, Socket type (note 2) and protocol, these three parameters determine which
type of network is transmitted Service provider to start the Network transport service function. All network traffic is the
process is more helpful to understand, because the previous article has mentioned that the network transport service provider is the Svchost.exe The
service process is loaded. The
describes the interface hierarchy between the network application, the CSocket (WSock32.dll), Socket
API (Ws2_32.dll), and the network transport service process:

/span>


When the client socket communicates with the Server-side socket, both ends trigger the socket
Event. Only two socket events are briefly described here:
Fd_connect: Connection event, usually client-side socket call Socket API function
When Connect is triggered, this event occurs on the client side.
Fd_accept: The connection event being introduced, typically the Server-side socket is receiving a
Triggered when the client side socket is connected, this event occurs on the Server side.
The network transport service process saves the socket event to the socket's event queue. In addition
The network transport service process also sends a message to the socket window wm_socket_notify, notifying
There is a socket event generated, see below for a detailed description of the socket window.
After calling the Csocket::create function, the socket is created. Called during the socket creation process
Casyncsocket::attachhandle (SOCKET hsocket, casyncsocket* psocket, BOOL
Bdead). The function is:
Adds the socket instance handle and the socket pointer to the current module state (note 1).
A mapping table variable in M_pmapsockethandle.
In the Attachhandle process, a new Csocketwnd instance (based on CWnd
This example is referred to as the socket window, further understanding that it is the storage of all
Sockets of the Message Pool (window message), please look carefully, here the socket after the add a
s, which means that multiple sockets created will share a single message pool.
When the client-side socket communicates with the Server, the network transport service process
To send a message to the socket window wm_socket_notify, you need to note that the Csocketwnd window
The port handle is stored in the M_hsocketwindow variable of the current module state.

2. Blocking mode
In blocking mode, the communication between the Server side and client side is in a synchronized state. In the Server
The CSocket class is instantiated directly by invoking the Create method, creating the socket, and then calling the method
Listen starts listening and finally uses a while loop block to call the Accept function to wait for the
Client-side connection, if the socket is running in the main thread (master program), this will cause the mainline
The block of the process. Therefore, you need to create a new thread to run the socket service.
Debug trace to csocket::accept function source code:
while (! Accept (...))
{
//The socket is marked as nonblocking and no connections were present to be accepted.
if (GetLastError () = = Wsaewouldblock)
PumpMessage (fd_accept);
Else
return FALSE;
}
It constantly calls Casyncsocket::accept (CSocket derived from the CAsyncSocket class)
Determine if there is a connection event being introduced in the event queue of the Server-side socket-
Fd_accept (see 1), in other words, is to determine if there is a connection from the client socket
The request is received.
If there is a connection event being introduced in the event queue of the current Server-side socket,
Accept returns a value other than 0. Otherwise, Accept returns 0, at which point the call to GetLastError will
Returns the error code Wsaewouldblock, which indicates that there are no connection requests in the queue. Notice in the loop body
Inside there is a code: PumpMessage (fd_accept);
PumpMessage as a message pump allows messages in the socket window to be maintained in the active
State. The actual trace enters the PumpMessage and discovers the call of this message pump and the Accept function and
Irrelevant, it just makes very few socket window messages (typically WM_PAINT windows redraw
The majority of the socket window messages are blocked, blocked messages
Contains wm_socket_notify.
Obviously, if there is no connection request from the client socket, CSocket will continue to
Call Accept causes loop blocking until a connection request from the client socket is released
Blocking.
When the blocking is lifted, the Server-side socket and client-side sockets are successfully connected.
The Server side and Client side call each other to Send and Receive methods to begin communication.

3. Non-blocking mode
Using the message mechanism of socket event in nonblocking mode, Server side and client side
The communication between them is in an asynchronous state.
You typically derive a new class from the CSocket class to derive the new class to overload the socket event
Message function, and then add the appropriate code in the message function of the socket event to complete the Client
Communication between the end and Server side, non-blocking mode does not need to create a new thread compared to the blocking mode.
This will discuss when the Server-side socket event-fd_accept is triggered, the event's
How the handler function onaccept is further triggered. Other event handling functions such as OnConnect,
OnReceive, etc., are triggered in a similar way.
When Client/server-side communication is mentioned in 1, the Server-side socket is receiving
Client-side socket connection request, which will trigger the Fd_accept event, while the Server-side
The network transport service process sends an event pass to the Server-side socket window (CSOCKETWND)
Know the news wm_socket_notify, notify the Fd_accept event, Csocketwnd received
After the event notification message, call the message handler function Onsocketnotify:
LRESULT csocketwnd::onsocketnotify (WPARAM WPARAM, LPARAM LPARAM)
{
Csocket::auxqueueadd (Wm_socket_notify, WParam, LParam);
CSocket::P rocessauxqueue ();
return 0L;
}
The message parameter WParam is the handle to the socket, and LParam is the socket event. A little bit here.
Explain that the Csocketwnd class is a friend of the CSocket class, which means that it can access
Protection and private member functions and variables in the CSocket class, Auxqueueadd and Processauxqueue
is the static member function of the CSocket class, if you are not familiar with friends, please quickly find this about C + + book
Take a look at the way you use your friends!
Processauxqueue is a function that essentially handles the socket event, in which there is a code in this function:
casyncsocket* Psocket = Casyncsocket::lookuphandle (SOCKET) WParam,
TRUE);
In fact, the socket pointer that gets the event notification message sent by the socket handle
Psocket: Find it from the M_pmapsockethandle (see 1)!
Finally, Wsagetselectevent (LParam) takes out the event type, in a simple switch
Statement to determine the type of event and invoke the event handler function. Here, the event type is fd_accept, when
Then call Psocket->onaccept!
concluding remarks
The Server-side socket is in blocking invocation mode and must be in a newly created thread
Prevent the main thread from being blocked.
When there are multiple client sockets connecting to and communicating with the server side socket, the server
Blocking mode is not appropriate, should use non-blocking mode, using the socket event
Message mechanism to accept connection requests from multiple client-side sockets and communicate.
In nonblocking mode, the use of Csocketwnd as a message pool for all sockets is implemented
The key technology for the message mechanism of the socket event. There are some technical problems in the article, such as the improper use of words and possible
Please forgive, please also criticize, thank you!
Note:
Current module state-a structure that holds the current thread and module state, which can be
Afxgetthreadmodule () obtained. Afx_module_thread_state redefined in CSocket
For _afx_sock_thread_state.
Socket type-in the TCP/IP protocol, the Client/server Network program uses the TCP protocol:
That is, the socket type is SOCK_STREAM, which is a reliable way to connect. The UDP Association is not used here
: The socket type is SOCK_DGRAM, which is an unreliable connection method.

"MFC Network Programming" learning Diary 3

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.