MFC-based socket programming (asynchronous non-blocking communication)

Source: Internet
Author: User
Tags network function

For many beginners, the development of network communication programs, a common phenomenon is that it is difficult to start. Many concepts, such as sync/async (async), blocking (block)/non-blocking (Unblock), and so on, beginners are often confused, only know the reason why they do not know.


Asynchronous means that the sender does not wait for the receiver to respond, then sends the next packet of communication, and synchronization refers to the sender after the data, and so on the receiving party sends back the response, only send the next packet of communication mode.
A blocking socket is a network call that executes this socket until it is successfully returned, or is blocked on this network call, such as calling the Recv () function to read the data in the network buffer, and if no data arrives, it hangs on the function call of recv () until some data is read. This function call is returned, whereas a non-blocking socket refers to a network call that executes the socket and returns immediately regardless of whether the execution succeeds. For example, calling the Recv () function reads the data in the network buffer, regardless of whether or not the data is read immediately, and does not hang on to this function call. Asynchronous non-blocking sockets are the most used in real-world Windows network communication software development. What is commonly referred to as the C/s (client/server) structure of the software is asynchronous non-blocking mode.
For these concepts, the beginner's understanding may only be plausible, and I will use one of the simplest examples to illustrate the basic principles and working mechanisms of asynchronous nonblocking sockets. The goal is to allow beginners to not only have a very thorough understanding of the concept of socket asynchronous nonblocking, but also provide them with a quick Start method for developing network communication applications with sockets. The operating system is Windows 98 (or NT4.0) and the development tool is visual c++6.0.
MFC provides an asynchronous class CAsyncSocket, which encapsulates the basic functions of asynchronous, non-blocking sockets, and it is convenient to use it for common network communication software. However, it masks the asynchronous, non-blocking concepts of the socket, and the developer does not need to understand the principle and working mechanism of asynchronous, nonblocking sockets. Therefore, it is recommended that beginners learn to compile the network communication program, but do not use MFC provides classes, and first with the Winsock2 API, which helps to understand the asynchronous, non-blocking socket programming mechanism.
For simplicity, both the server side and the client application are standard MFC-based dialogs, and the network communication section is based on the Winsock2 API implementation.
Do server-side applications first.
Use the MFC Wizard to make a dialog-based application Socketsever, and note that the WINDWOS sockets option is not selected in the third step. After doing the project, create a seversock, set it to asynchronous nonblocking mode, register various network asynchronous events for it, and then contact the custom network asynchronous event, and finally set it to listening mode. In the callback function of the custom network asynchronous event, you can get various network asynchronous events, depending on their type, do different processing. Here's a detailed description of how to write the relevant code.
Add the following definition before the class definition for the SocketSeverDlg.h file:
#define Network_event wm_user+166 file://defining network Events

SOCKET Serversock; file://server-side socket
Add the following definition to the class definition:
Class Csocketseverdlg:cdialog
{
Public
SOCKET Clientsock[clnt_max_num]; file://an array of sockets that store the communication with the client

/* processing functions for various network asynchronous events */
void OnClose (SOCKET cursock); file://-to-end socket disconnect
void OnSend (SOCKET cursock); file://Sending network packets
void OnReceive (SOCKET cursock); FILE://Network Packet Arrival
void OnAccept (SOCKET cursock); file://Client Connection request

       BOOL initnetwork ();     file://Initialize network functions
        void Onnetevent (WPARAM WPARAM, LPARAM LPARAM); file://Asynchronous Event callback function
                    ...
};
        
adds a message map in the SocketSeverDlg.cpp file, where Onnetevent is the name of the asynchronous event callback function:
       on_message (network_event,onnetevent)
defines the initialization of the network function, This function can be adjusted in the OnInitDialog () of the SocketSeverDlg.cpp file.
BOOL csocketseverdlg::initnetwork ()
{
       wsadata wsadata;

      //Initialize TCP protocol
       BOOL ret = WSAStartup ( Makeword (2,2), &wsadata);
       if (ret! = 0)
       {
            MessageBox (' Initialize network protocol failed! ');
           return FALSE;
      }

Create a server-side socket
Serversock = socket (af_inet, sock_stream, ipproto_tcp);
if (Serversock = = Invalid_socket)
{
MessageBox (' Create socket failed! ');
Closesocket (Serversock);
WSACleanup ();
return FALSE;
}

Bind to a local port
Sockaddr_in localaddr;
localaddr.sin_family = af_inet;
Localaddr.sin_port = htons (8888); Port number does not conflict with other applications
localaddr.sin_addr.s_addr = 0;
if (bind (Serversock, struct sockaddr*) &localaddr,sizeof (sockaddr))
= = Socket_error)
{
MessageBox (' Bind address failed! ');
Closesocket (Serversock);
WSACleanup ();
return FALSE;
}
Sets the Seversock to asynchronous nonblocking mode and registers various network asynchronous events for it, where m_hwnd
Handle to the main dialog box or main window of the application
if (WSAAsyncSelect (Serversock, M_hwnd, network_event, fd_accept | Fd_close | Fd_read | fd_write) = = Socket_error)
{
MessageBox (' Register network asynchronous event failed! ');
WSACleanup ();
return FALSE;
}
Listen (Serversock, 5); file://Setting the Listening mode
return TRUE;
}

The following defines the callback function for the network asynchronous event
void Csocketseverdlg::onnetevent (WPARAM WPARAM, LPARAM LPARAM)
{
Call the Winsock API function to get the network event type
int iEvent = wsagetselectevent (LParam);
Call the Winsock API function to get the client socket that this event occurs
Socket cursock= (socket) WParam;

Switch (iEvent)
{
Case FD_ACCEPT://Client Connection request event
OnAccept (Cursock);
Break
Case Fd_close://Client Disconnect event:
OnClose (Cursock);
Break
Case FD_READ://Network Packet arrival event
OnReceive (Cursock);
Break
Case Fd_write://Send network data event
OnSend (Cursock);
Break
Default:break;
}
}

The following are the processing functions of various network asynchronous events that occur on the corresponding sockets, where the parameters passed in by OnAccept are the server-side created sockets, OnClose (), OnReceive (), and OnSend () The incoming parameters are the server-side socket that was created in the client connection to communicate with this client.
void Csocketseverdlg::onaccept (SOCKET cursock)
{
Accept the connection request and save the client that originated the connection request to communicate with the socket
Registering asynchronous events for a new socket, note that there is no accept event
}
void Csocketseverdlg::onclose (SOCET cursock)
{
End communication with the corresponding client and release the appropriate resources
}

void Csocketseverdlg::onsend (SOCET cursock)
{
preprocessing when sending data to the client
}

void Csocketseverdlg::onreceive (SOCET cursock)
{
read out packets in the network buffer
}

Build a client application in the same way. Initializes the network section without having to set the socket to listen mode. When registering an asynchronous event, there is no fd_accept, but the Fd_connect event is added, so there is no onaccept () function, but the OnConnect () function is added. When a connection request is made to the server, the Connect () function is used to respond to the OnConnect () function when the connection is successful. The following is the definition of the OnConnect () function, which is the flag that the client socket and the server-side send back the success of the connection.
void Csocketclntdlg::onconnect (SOCKET cursock, int error)
{
if (0 = = error)
{
if (Cursock = = Clntsock)
MessageBox (' Connection server succeeded! ');
}
}
Define the OnReceive () function to handle network data arrival events;
Define the OnSend () function to handle sending network data events;
Define the OnClose () function to handle the server's Shutdown event.

The above is the basic method for server and client applications using the Windows Messaging mechanism-based asynchronous I/O model. You can also use the event model, overlapping model, or completion port model for readers to refer to the books.
After implementing the above example, you will have a certain understanding of the mechanism of the Winsock Knitting Network communication program. Next you can do more exciting programming, not only can transfer the normal data on the Internet, but also to transmit voice, video data, you can also do a network resource sharing Server software, and your classmates in the lab's local area network can share your results.

The synchronization server socket suspends execution of the application until a connection request is received on the socket. Synchronous server sockets are not suitable for applications that use a large number of networks in operations, but they may be suitable for simple network applications. After you set up the socket with the Bind and Listen methods to listen on the endpoint, the socket can accept incoming connection requests at any time using the Accept method. The application is suspended until a connection request is received when the Accept method is called.


When a connection request is received, accept returns a new Socket instance associated with the connection client. The following example reads the client data, displays the data on the console, and then echoes the data back to the client. The Socket does not specify any message protocol, so the string "<EOF>" marks the end of the message data. It assumes that a Socket named Listener is initialized and bound to an endpoint.

Console.WriteLine ("Waiting for a Connection ...");
Socket handler = listener. Accept ();
String data = null;

while (true) {
bytes = new byte[1024];
int Bytesrec = handler. Receive (bytes);
Data + = Encoding.ASCII.GetString (Bytes,0,bytesrec);
if (data. IndexOf ("<EOF>") >-1) {
Break
}
}

Console.WriteLine ("Text Received: {0}", data);

byte[] msg = Encoding.ASCII.GetBytes (data);
Handler. Send (msg);
Handler. Shutdown (Socketshutdown.both);
Handler. Close ();

MFC-based socket programming (asynchronous non-blocking communication)

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.