Abstract: Based on the actual needs, this article uses network programming technologies such as Windows Socket API to achieve a LAN sharing of a telephone line, when the server dial-up accesses the Internet, the client can be notified to access the Internet through the proxy server in a timely manner. This article also provides some key implementations based on Microsoft Visual C ++ 6.0. Code .
I. background
The LAN used by the author has a server and a number of clients distributed in various offices, connected through the NIC. The server does not provide leased line Internet access, but can dial-up Internet access. Each client can access the Internet through a telephone line through the proxy server installed on the server, provided that the server has been connected by dial-up. For economic reasons, the server cannot be connected to the Internet for a long time. Therefore, it is often because clients distributed in different offices cannot know whether the server is connected, or when the server has been dial-up but the client is not aware of it, this will undoubtedly cause great inconvenience in the work. AsProgramIt is necessary for the designers to use their professional advantages to solve some problems encountered in practical work. By analyzing the actual situation, we can conclude that when the server performs a dial-up connection, it can notify clients on the network in a timely manner, each client can decide whether to access the Internet based on its own situation after receiving a message from the server. In this way, you can provide Internet services for a large number of clients at the same time, which not only improves the utilization efficiency, but also greatly saves the Internet calls.
Ii. Main program design ideas and implementation
Because the network is connected through the LAN, you can use Windows Socket API for socket programming. The entire system is divided into two parts: the server and the client. The server is running on the server and is responsible for monitoring whether the server is making a dial-up connection. Once discovered, the server immediately sends a message to the client through the network; the client software only needs to connect to the server software and receive notifications sent from the server. The server must complete more complex tasks than the client. The following describes the implementation of these parts:
(1) monitoring the occurrence of dial-up connection events
When using dial-up Internet access, you must first connect to the ISP through a dial-up connection through a telephone line before you can enjoy various Internet services provided by the ISP. The events to capture the dial-up connection do not depend on message notifications, because the messages generated when the same dialog box appears on the screen are the same. The only difference from other dialogs is that the title is a fixed "dial-up connection", so in no special circumstances (for example, when the title of other programs is "dial-up connection) when all program windows on the desktop appear with the title "dial-up connection", you can identify that a dial-up connection is in progress. Therefore, you can monitor dial-up connections by searching for and judging the window title. You can use the findwindows () function of the cwnd class to implement the following:
Cwnd * pwnd = cwnd: findwindow (null, "dial-up connection "); |
The first parameter is null, which specifies to search all current windows. The second parameter is the title of the window to be searched. Once found, the window handle of the window is returned. Therefore, when the window handle is not empty, the client server can be notified to be dialing now. Generally, it takes some time for a dial-up connection to respond before logging on to the ISP, therefore, from the perspective of improving the program running efficiency, you can use the timer to search every interval (for example, 500 milliseconds, to ensure that each dial-up connection can be monitored without increasing the CPU burden.
(2) Implementation of network communication functions on the server side
The reliable and connected stream socket is used here, and the multi-thread and asynchronous notification mechanisms can effectively avoid blocking of some functions such as accept (), which will cause the entire program. Due to the wide variety of books and materials on socket programming, network programming is described in detail. Therefore, this article only briefly describes some key parts here, for more information about Socket network programming, see related documents. The main design process of the server using streaming sockets can be summarized as follows:
1. Create a socket
Sock = socket (af_inet, sock_stream, 0 ); |
The first parameter of this 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 the closesocket () function to release it before exiting the program.
2. Bind a socket
Once the server obtains a new socket, BIND () should be used to associate the socket with a port on the local machine. In this case, you need to fill in necessary information, such as the local port number and the local host address, to a sockaddr_in structure containing the local IP address and port information in advance. Then, the server process can be identified on the network through BIND. Note that port numbers smaller than 1024 are reserved. Therefore, you cannot set the port number of sockin. sin_port to a value smaller than 1024 unless otherwise required:
...... Sockin. sin_family = af_inet; Sockin. sin_addr.s_addr = 0; Sockin. sin_port = htons (userport ); BIND (sock, (lpsockaddr) & sockin, sizeof (sockin )); ...... |
3. listening socket
4. Wait for the Client Connection
You need to call accept () to wait for the connection from the receiving client to establish the connection. Because the function is blocked before the client applies for a connection, therefore, if the common single-thread mode is adopted, the entire program will remain in the blocking state and cannot respond to other external messages. Therefore, a separate thread is opened for this part of code, in this way, blocking will be restricted within the thread without affecting the entire program.
Afxbeginthread (server, null); // create a new thread ...... Uint server (lpvoid) // thread processing function { // Obtain the pointer of the current video class to ensure that the current instance object is accessed. Cnetserverview * pview = (cnetserverview *)( (Cframewnd *) afxgetapp ()-> m_pmainwnd)-> getactiveview ()); While (pview-> nnumconns <1) // number of current connectors { Int nlen = sizeof (sockaddr ); Pview-> newskt = accept (pview-> sock, (Lpsockaddr) & pview-> sockin, (lpint) & nlen ); Wsaasyncselect (pview-> newskt, Pview-> m_hwnd, wm_socket_msg, fd_close ); Pview-> nnumconns ++; } Return 1; } |
Here, the wsaasyncselect () asynchronous selection function is used after accept. It is best to adopt an asynchronous selection mechanism to respond to network events. Only in this way can unpredictable network events caused by the other party of the network be immediately responded to and handled 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 is the core function for asynchronous selection of network events. The fourth parameter fd_close is used to register a network event that the application is interested in. This event is detected when the client opens a connection, the custom message wm_socket_msg specified by the third parameter is also sent.
5. Send/receive
After the client establishes a connection with the server, it can send and receive data through the send ()/Recv () function, for this program, you only need to send a notification message to the client when a dial-up connection event is detected:
Char buffer [1] = {'A '}; Send (newskt, buffer,); // send the character a to the client, indicating that the server is dialing now. |
6. Disable socket
After all communications are completed, you need to call closesocket () before exiting the program. The function closes the created socket.
(3) client-side Program Design
Client programming is much simpler. The entire communication process only takes the following four steps:
1. Create a socket
2. Establish a connection
3. Send/receive
4. Disable socket
The specific implementation process is similar to that of Server programming, but the network events to be monitored are fd_close and fd_read because data needs to be received, in the message response function, you can identify the specific network event and respond to it by determining the low byte of the message parameter. The following code is used to explain the implementation process:
...... M_servip = serverip; // specify the IP address of the server. M_port = htons (userport); // specify the server port number If (ipaddr = inet_addr (m_servip) = inaddr_none) // convert to a network address Return false; Else { Sock = socket (af_inet, sock_stream, 0); // create a socket Sockin. sin_family = af_inet; // fill Structure Sockin. sin_addr.s_un.s_addr = ipaddr; Sockin. sin_port = m_port; Connect (sock, (lpsockaddr) & sockin, sizeof (sockin); // establish a connection // Set the asynchronous selection event Wsaasyncselect (sock, m_hwnd, wm_socket_msg, fd_close | fd_read ); // Here, You can notify the customer that the server has been connected by means of the earthquake Bell, pop-up dialog box, etc. } ......// Message processing function for network events Int message = lparam & 0x0000ffff; // obtain the low Message Parameter Switch (Message) // determine the network event { Case fd_read: // read event Afxbeginthread (read, null ); Break; Case fd_close: // server Close event ...... Break; } |
In the message processing process of a read event, a separate thread is opened for the read process to receive information sent from the server, and notify the client that the server is dialing through the following means:
...... Int A = Recv (pview-> sock, cdatabuffer,); // receives messages sent from the server If (a> 0) Afxmessagebox ("the dial-up connection has been started! "); // Notify the user ...... |
3. Necessary improvements
The previous section only introduced the overall framework and Design Concept of the program design. It is just a prototype, and many important details are incomplete and cannot be used in practical use. The following describes the necessary details:
(1) Hide the interface
Because this program is automatic detection and notification and does not require manual intervention, it can be regarded as a service program running in the background. Therefore, the main interface of the program is no longer necessary, you can change the parameter sw_show of showwindow (); To sw_hide in the initinstance () function of the initialization instance of the application class. When a dialog box is required to bring up a notification to the user, only the dialog box appears and the main interface is hidden. Therefore, it is completely feasible.
(2) self-starting implementation
Because the server software needs to monitor whether there is a dial-up connection at any time, it must have the characteristics of self-starting. The client software can automatically complete receiving messages and notifying customers. Therefore, if the client software can enable itself, it can achieve a high degree of automation without user intervention. To set the auto-start feature, you can consider the following ways:
1. Add a shortcut to the program on the "Start" menu.
2. Add the command line for starting the program in autoexec. bat.
3. Add the program path after running the project in the [windows] section of win. ini.
4. Modify the registry. The specific path for adding a key value is:
"HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Run"
Modify the added key value to the program storage path. The preceding methods can be manually added or automatically completed by programming.
(3) Automatic Connection resumption
For network communication programs in service/customer mode, it is generally required that the server should run before the client. The customers and servers of the system are self-started, and the server cannot be started before the client, in addition, the system requires that the client and server be connected to the network without interruption. Therefore, both the client and the server must have the automatic connection function.
On the server side, when the client is disconnected, you need to close the current socket and restart a new socket to wait for the client to connect again. This can be done in the message response function of the message wm_socket_msg corresponding to the fd_close event. If the client is started before the server, the connect () function will return a failure. Therefore, you can use settimer () to set a timer at the startup of the program) try to connect to the server once. When the connect () function returns a success, that is, the server is started and connected to it, you can use the killtimer () function to close the timer. In addition, when the server is shut down, you need to enable the timer again to ensure that a connection can be established when the server runs again. You can capture the event by responding to the fd_close event.
Summary:This article uses the Windows Sockets API to design a network communication program for connection-oriented stream sockets based on TCP/IP protocol, with the support of network communication programs, you can promptly notify the client of the events of the dial-up connection captured by the server, at last, some necessary details are improved to solve the problem of timely server dialing connection notifications on the LAN. The program described in this article is compiled by Microsoft Visual C ++ 6.0 under Windows 98 SE. the proxy server software used is Wingate 4.3.0, and the Internet access method is dial-up.