Asynchronous Network Communication using the Windows Sockets API

Source: Internet
Author: User

[Article Information]Author: Institute of Electronics 22nd, Ministry of Information Industry, Qingdao branch Lang Rui time: Source: yesky Editor: Ark[Document Introduction]This article discusses and explains how to use a connection-oriented stream socket to program the NIC and How to Implement Asynchronous Network Communication.

Abstract:This article discusses how to use connection-oriented stream sockets to program NICs and How to Implement Asynchronous Network Communication.

I. Introduction

In early 1980s, researchers at the University of California Berkeley developed an API specifically for network communication for TCP/IP network communication. This API is the Socket interface (Socket), the most common API in the TCP/IP network today, and the most common API for application development on the Internet. After Microsoft and several other companies jointly developed a set of Windows Network Programming Interface Windows Sockets specifications, some asynchronous functions were introduced in the specification, the Asynchronous Network Event Selection Mechanism is added, so it is more in line with the message-driven features of Windows, so that network developers can design high-performance network communication programs more conveniently. Next, we will discuss connection-oriented stream socket programming for Windows Sockets APIs and programming implementation for Asynchronous Network Communication.

Ii. connection-oriented stream socket programming model design

In this article, the client/server model, which is the most common model in network programming, is used in the solution selection. This client/server model is an asymmetric programming model. The basic idea of this mode is to divide applications that are centralized into two parts with different functions and run them on different computers, A complete function is achieved through the division of labor and cooperation between them. In this mode, some of them need to be used as servers to respond to and provide customers with fixed services, while others are used as client programs to request or request a service from the server.

This article selects the TCP/IP-based client/server model and connection-oriented streaming socket. The communication principle is: both the server and the client must establish a communication socket, and the server should first enter the listening status, and then the client socket sends a connection request. After the server receives the request, establish another socket for communication. The socket originally responsible for listening is still listening. If other customers send a connection request, create another socket. By default, you can receive connection requests from up to five customers at the same time and establish a communication relationship with them. Therefore, the design process of this program should be started by the server first, and then start the client at a certain time point and establish a connection with the server. Both the server and client must call the Windows Sockets API function socket () to create a socket sockets. Then the server calls bind () to bundle the socket with a local network address, call listen () to make the socket in a passive ready-to-receive state, and specify its request queue length. After that, the server can call accept () to receive client connections.

Compared with the server, the client's work is relatively simple. After the client opens the socket, you can call connect () to establish a connection with the server. After the connection is established, the customer and the server can send and receive data through the connection. Finally, the data transfer is complete. Both parties call closesocket () to close the socket to end the communication. The specific process diagram of the entire communication process can be expressed in the following flowchart:

Connection-oriented stream socket programming process
Iii. Key Points of Software Design and Implementation of Asynchronous Communication

Based on the previously designed program process, the program can be divided into two parts: the server side and the client side. In addition, the following key Windows Sockets API functions can be used in the entire implementation process:

Server side:

socket()-> bind()-> listen-> accept()-> recv()/send()-> closesocket()
Client Side:

socket()-> connect()-> send()/recv()-> closesocket()
In view of the importance of the above functions in the network programming, it is necessary to analyze them in depth with program instances. Before using a Socket, a server application must have a socket. The system calls the Socket () function to create a socket for the application. The socket actually provides a communication port in the computer, which can be used to communicate with any computer with a socket interface. The information transmitted and received by applications over the network is implemented through this socket interface. In application development, you can perform read and write operations on the socket handle just like using a file handle:

sock=socket(AF_INET,SOCK_STREAM,0);
The first parameter of the function is used to specify the address family. In Windows, only AF_INET (TCP/IP address) is supported. The second parameter is used to describe the socket type. for streaming sockets, SOCK_STREAM is provided; the last parameter specifies the protocol used by the socket, which is generally 0. The return value of this function saves the handle of the new socket. You can use closesocket (sock) before exiting the program. The function releases the new socket. Once the server obtains a new socket, bind () should be used to associate the socket with a port on the local machine:

sockin.sin_family=AF_INET;
sockin.sin_addr.s_addr=0;
sockin.sin_port=htons(USERPORT);
bind(sock,(LPSOCKADDR)&sockin,sizeof(sockin)));

The second parameter of this function is a pointer to the sockaddr_in structure containing the local IP address and port information. Its members describe the local port number and the local host address () identifies a server process on the network. Note that the port numbers within 1024 are reserved. Therefore, you cannot set the port number of sockin. sin_port to within 1024 unless otherwise required. Then call the listen () function to start listening, and then call accept () to wait for the received connection to establish the connection:

// The length of the Connection Request queue is 1, that is, only one request is allowed. If multiple requests exist,
// An error occurs. The error code WSAECONNREFUSED is provided.
Listen (sock, 1 );
// Enable the thread to avoid blocking the main program
AfxBeginThread (Server, NULL );
......
UINT Server (LPVOID lpVoid)
{
......
Int nLen = sizeof (SOCKADDR );
PView-> newskt = accept (pView-> sock, (LPSOCKADDR) & pView-> sockin, (LPINT) & nLen );
......
WSAAsyncSelect (pView-> newskt, pView-> m_hWnd, WM_SOCKET_MSG, FD_READ | FD_CLOSE );
Return 1;
}

The reason for putting accept () in a thread is that if the client does not connect to the server when the function is executed, the server will stop on the accept statement and wait for the connection request to arrive, this will inevitably cause program blocking, although you can also set the socket to be non-blocking, so that the accept () function call can be returned immediately when no client waits, however, this method of polling sockets will make the CPU in a busy waiting manner, thus reducing the program running efficiency and greatly wasting system resources. In this case, the socket is set as a blocking method, and a sub-thread is opened for it separately. Blocking is controlled within the sub-thread range without blocking the entire application. Asynchronous selection mechanism is needed for the response to network events, only in this way can we immediately respond to unpredictable network events caused by the peer network in a timely manner in the process, other events can be handled when no network event arrives. This efficiency is very high and fully complies with the message trigger principle advertised by Windows. The WSAAsyncSelect () function in the previous code is the core function for asynchronous selection of network events.
You can use the fourth parameter to register the network events that the application is interested in. Here, you can use FD_READ | FD_CLOSE to specify the network read and network disconnection events, when such an event occurs, the custom message WM_SOCKET_MSG specified by the third parameter is sent. The window that receives the message specifies its handle through the second parameter. In the message processing function, you can identify the low bytes of the Message Parameter and determine the network events generated based on the difference:

Void CNetServerView: OnSocket (WPARAM wParam, LPARAM lParam)
{
Int iReadLen = 0;
Int message = lParam & 0x0000FFFF;
Switch (message)
{
Case FD_READ: // read event occurs. At this time, there are characters that need to be received and processed
Char cDataBuffer [MTU * 10];
// Receive information through socket
IReadLen = recv (newskt, cDataBuffer, MTU * 10, 0 );
// Save the information to the file
If (! File. Open ("ServerFile.txt", CFile: modeReadWrite ))
File. Open ("E: ServerFile.txt", CFile: modeCreate | CFile: modeReadWrite );
File. SeekToEnd ();
File. Write (cDataBuffer, iReadLen );
File. Close ();
Break;
Case FD_CLOSE: // The Network disconnection event occurs. In this case, the client closes or exits.
...... // Perform corresponding processing
Break;
Default:
Break;
}
}

Here we need to implement the response to the custom message WM_SOCKET_MSG. We need to add the message ing relationship in the header file and the implementation file respectively:

Header file:

//{{AFX_MSG(CNetServerView)
//}}AFX_MSG
void OnSocket(WPARAM wParam,LPARAM lParam);
DECLARE_MESSAGE_MAP()

Implementation file:

BEGIN_MESSAGE_MAP(CNetServerView, CView)
//{{AFX_MSG_MAP(CNetServerView)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_SOCKET_MSG,OnSocket)
END_MESSAGE_MAP()

When using the WSAAsyncSelect () function asynchronously, pay special attention to the following points:

1. When the WSAAsyncSelect () function is used twice in a row, only the second set event is valid, for example:

WSAAsyncSelect(s,hwnd,wMsg1,FD_READ);
WSAAsyncSelect(s,hwnd,wMsg2,FD_CLOSE);

In this way, wMsg2 messages are sent only when the FD_CLOSE event occurs.

2. You can use

Related Article

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.