Multi-User LAN communication based on TCP/IP

Source: Internet
Author: User

Due to the rapid popularity of the Internet, more and more applications are capable of communicating with other programs online. Since Win95, Microsoft has integrated network functions into its operating system, making the network communication capability of applications more popular. Therefore, Microsoft's TCP/IP Protocol becomes the preferred protocol for network applications.

Generally, applications using TCP/IP protocol only implement point-to-point connections between a single user and the server. This article uses multithreading and shared data structure technology in the vc6.0 environment, it not only realizes connections between multiple users and servers, but also solves the problem of information exchange among multiple users-relying on the server's forwarding function. Through the elaboration in this article, we hope to inspire readers who need to write multi-user network communication programs.

I. Technical Overview

1.1 TCP/IP-based communication technology

TCP/IP-based communication basically uses Socket Sockets for data communication. The program is generally divided into two parts: the server side and the client side. The following is a brief introduction to the design concept (under vc6.0 ):

Part 1 Server
1. Create a server socket ).
2. Bind the server socket and start listening for the listen ).
3. Accept access requests from the client ).
4. Start data transmission (send/receive ).
5. Close the socket (closesocket ).

Part 2 client
1. Create a user socket ).
2. Connect to the remote server. If accepted, a receiving process is created.
3. Start data transmission (send/receive ).
4. Close the socket ).

With the above design ideas, we can create a simple connection-oriented single-user program. Next, we will introduce the multithreading technology to enable the program to support multiple users.

1.2 multithreading technology

We can regard a thread as an execution point in a process (Execution Program). Each process may have several threads running at any given time. All threads in a process share the same address space, Data, code, and resources in the process. Each thread in a process has its own stack space, which is separated from other threads and cannot access each other. Each thread runs in either time slice rotation or priority mode during the CPU time occupied by the process. If the task is run in time slice rotation mode, each thread obtains the same amount of time. If the task is run in priority mode, the thread with a higher priority gets more time, low-priority threads can only get a small amount of time. The method selection mainly depends on the system time scheduler mechanism and the real-time requirements of the program.

Now, multi-thread technology can be used to support multiple users. That is, on the server side, the infinite loop of receiving connection requests (accept) from the client side is generated. Each time a user request is received, two threads (send and receive threads) are generated ), used to manage the communication tasks between the server and the user. Next, we can use the shared data structure technology to implement the key technology to be addressed in this question-server forwarding technology.

1.3 shared data structure technology

Multiple threads in the same process coexist in a single linear address space. Therefore, it is very easy and convenient to share the data structure among multiple threads. However, you must note that the access to the data structure must be multi-threaded and mutually exclusive. Otherwise, any changes to the data will lead to unpredictable results. The server forwarding technology described in this article is to implement inter-thread communication through the shared data structure.

II. Implementation Scheme

The entire system is divided into three related programs: Registration/login server, Communication Server and user program. The registration/login server is responsible for user registration, login, and database management. The communication server is responsible for managing data forwarding and shared data structures. The user end completes registration, login, and communication functions. Why is the server divided into two parts? It mainly takes into account the User Capacity of the server and the protection for the communication server. Only after the verification is passed, the user can connect to the communication server.

It can be seen that the implementation of the entire system communication task is still very complicated. The user end must register the user first, and wait until the registration is successful. Then, the user can log on to the server based on the registration information. After the login is successful, the user can connect to the Communication Server for communication between users.

After the registration/login server receives information from the user end, it first determines whether it is the registration information or the login information. If the registration information is used, the data is written to the database in a predetermined format, and a successful registration message is returned. If any exception occurs during the registration, the server returns the registration failure message, prompt the user to re-register; if it is login information, extract the user name and ID from the data and compare it with the content in the database. If the user exists, return the login success message. Otherwise, returns the logon failure message.

The Communication Server performs data forwarding by interacting with the shared data structure in the figure. After receiving a message from the client, the server extracts a part of the message and compares it with the content stored in the shared data structure, determines the object to be forwarded, and forwards the data through multithreading and communication mechanisms. Next, we will discuss the specific implementation process of the system in three parts.

 

 

Iii. Implementation

3.1 register/log on to the server

The registration/login server program is based on the dialog box. The program uses port 56789 of I/O to connect to the user end.
First, complete the network initialization while initializing the dialog box, that is, execute the init_net () function. The Code (incomplete) is as follows:

Bool cserverdlg: init_net () ///////////// ////////////// addrlen = sizeof (sockaddr_in ); status = wsastartup (makeword (1, 1), & data );......... Memset (& serversockaddr, 0, sizeof (serversockaddr);/* specify a local or remote address to connect to a socket */serversockaddr. sin_port = htons (port); serversockaddr. sin_family = af_inet; serversockaddr. sin_addr.s_addr = htonl (inaddr_any); serversocket = socket (af_inet, sock_stream, 0); // initialize the socket ......... Status = BIND (serversocket, (lpsockaddr) & serversockaddr, sizeof (serversockaddr); // bind the socket to the address ......... Status = listen (serversocket, 5); // start listening ......... Return true ;}

Press the run key to start the server function and execute the reg_load () function, so that the server is always waiting for connection, but this also makes the thread always blocked. When a user connects, this function creates a task to process transactions with the user and the database. Specific task functions (see the original code file ).

Void cserverdlg: reg_load () {While (1) {cwinthread * hhandle; clientsocket = accept (serversocket, (lpsockaddr) & clientsockaddr, & addrlen); // wait for the connection, blocking hhandle = afxbeginthread (talktoclient, (lpvoid) clientsocket); // create a task when a connection exists .........}}

When a task function receives a message, it must operate on the database. Because the database is relatively simple, it uses ODBC to connect to the Access Database (netuser. MDB is installed as a data source of the same name in the ODBC Data Manager.) The specific code is omitted.

3.2 Communication Server

Communication Server is the key to the implementation of this program. It uses the technology of shared data structure and multithreading to connect to the user end through I/O port 56790, and implements the data forwarding function. First, the program initializes the network init_net (), and then creates the receiving thread and sending thread when the user connects to the server, so that data forwarding can be realized. Finally, when the user disconnects, the server closes the connection with the user and ends the corresponding thread.

Next, let's take a look at the specific content and usage of the shared data structure in this program, as well as the related content and implementation of multithreading.

● Shared data structure

The shared data structure of this program has two types: socket_info and send_info. The former contains some basic information about all login users, and the latter contains information sent by the client received by the current server. The details and comments are as follows:

Struct socket_info {socket s_client; // user's socket value u_long client_addr; // user's network address cstring PET; // user's nickname cwinthread * thread; // pointer to the sending thread object created for this user}; struct send_info {cstring data; // the data content sent by the user end (edited) cwinthread * thread; // task pointer for sending data };

In a program, two global variables are defined for sharing among threads:

 send_info info_data; CList<socket_info,socket_info&>s_info; 

When a user connects to the server, the server saves some information of the client to the s_info list in the form of a socket_info struct. When the server receives data sent from the client, format the data and save it to the struct info_data. Compare it with the struct list to determine the sending thread to be restored (all sending threads are suspended when they are created ). In this way, the server accurately forwards data.

● Multithreading

Each time a user successfully connects to the server, the server creates two threads for it: the receiving thread (recvdata) and the sending thread (senddata), and the receiving thread is executable after creation, the sending thread is blocked, waiting for the server to wake up. Both threads execute an infinite loop process. Only when an exception occurs in communication or the client closes the connection can the thread be terminated by itself, and the two threads must be generated at the same time, end at the same time. Obviously, each connection generates two threads, making data forwarding simple, but at the same time increasing server tasks. Therefore, the number of client connections is limited, depending on the server's software and hardware capabilities.

At the same time, because multithreading requires operations on the struct info_data, threads must be synchronized. Here, I have defined the mutex cmutex m_mutex and used its methods lock () and unlock () to complete synchronization.

Let's first look at the receiving thread (recvdata): (incomplete code)

Uint recvdata (void * cs) {socket clientsocket = (socket) Cs; while (1) {numrcv = Recv (clientsocket, buffer, maxbuflen, no_flags_set ); buffer [numrcv] = ''/0''; If (strcmp (buffer, "close! ")! = 0) // not the received "close" Data {............ For (I = 0; I <count; I ++) {If (Po! = NULL) {S1 = s_info.getnext (PO); If (s1.pet. compare (petname) = 0) // compare whether the nicknames are the same {m_mutex.lock (); // interlock info_data.data = Pos; info_data.thread = s1.thread; m_mutex.unlock (); // unlock} s1.thread-> resumethread (); // resume sending the corresponding thread break; }}} else {............ If (clientsocket = s1.s _ client) {m_mutex.lock (); // interlock info_data.data = buffer; m_mutex.unlock (); // unlock s1.thread-> resumethread (); // resume sending the corresponding thread s_info.removeat (PO1); // Delete the user information break ;}......... Goto AA ;}} AA: closesocketlink (lpvoid) clientsocket); // close connection afxendthread (0, true); // end this thread return 1 ;}

Next let's take a look at the sending thread (senddata): (incomplete code)

Uint senddata (void * cs) {socket clientsocket = (socket) Cs; while (1) {If (info_data.data! = "Close! ") {M_mutex.lock (); // interlock numsnd = Send (clientsocket, info_data.data, encrypt (), no_flags_set); // send data now = info_data.thread; m_mutex.unlock (); // unlock now-> suspendthread (); // suspend yourself} else {goto BB;} BB: closesocketlink (lpvoid) clientsocket); // close the connection to afxendthread (0, true); // end this thread return 1 ;}

3.3 Client

Obviously, the user end does not need to consider multithreading, and the network connection technology is also relatively mature. Therefore, there is no difficulty in communication. However, the user end is intended for actual users, so both interfaces and functions must be friendly. Like most software updates, the improvement of interface friendliness and functional perfection are often at the top of the list. It can be seen that from the perspective of overall design and technical implementation, the workload on the user side is very large, and the design is much more complicated than that on the server side. I have summarized the following:

● Compatible with the server communication format;

● Simple and easy to use, with beautiful interfaces and shortcut keys;

● Accurately receive and transmit data;

● All data recording and extraction functions;

● Multiple message receiving and prompting methods, such as the flickering Tray Icon (the sender's profile picture) and sound prompt;

Based on the above content, I designed three independent dialog boxes to complete registration, login, and communication functions. The login and registration dialog boxes are connected to the server's 56789i/O port, the Communication dialog box is connected to the 56790i/O port of the server, which isolates registration, login, and communication. This reduces the server load and ensures communication security.

As this part is not the main content, for detailed code, see the program.

Iv. Conclusion

Through the above description, we can know that the system is divided into server and client, and the server is divided into registration/login server and communication server, the forwarding function of the communication server enables multi-user communication in the LAN. This article uses multi-thread technology and shared data structure technology to implement the forwarding function of communication servers, so that network applications based on TCP/IP are generally developed. The system has run through the LAN (one server and 20 clients) in our lab.

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.