Implement WinSock programming with multiple threads

Source: Internet
Author: User
Tags export class

Author: Wang Guangwei Li weizhao

1. Introduction to windsock

Winsock (Windows Sockets) is part of Microsoft's window system structure (wosa. It is a socket based on the BER keley software distribution (BSD) version on UNIX and has been specially extended for Windows.
The Internet has developed on Unix systems. There are many mature programming interfaces on Unix. The most common interface is a socket interface. The essence of a socket is an abstraction of a communication endpoint. It provides a mechanism for sending and receiving data. Before and after 1991, many network software vendors were stepping up the development of TCP/IP communication components for Windows. In order to make these components have certain standards and reduce the development difficulty, they decided to develop a standard, universal TCP/IP programming interface for Windows and make it similar to sockets in Unix. This interface was quickly accepted by all software vendors, including Microsoft and IBM. By 1994, it was formally formulated as a standard, known as Windows Sockets or WinSock, and provided to users and software developers through the dynamic Connection Library in C language. We now see that Internet software under Wind ows is developed under Winsock. With the launch of Windows 95, Winsock has been formally integrated into Windows systems, and it also includes 16-bit and 32-bit programming interfaces.
The implementation of Winsock is generally composed of two parts: development components and running components. The development component is used by programmers to develop winso CK applications. It includes documents about Winsock implementation, Winsock application interface (API) import and receiving, and some header files. The running component is the dynamic connection library (DLL) of the Winsock application interface, and the file name is Winsock. dll. The network communication function is implemented by loading the application during execution.
Initially, winsock1.1 was designed specifically for the Internet. version X is no longer limited to the Internet and TCP/I p protocols. It provides extended SPI programming interfaces to extend its application scope to existing and emerging networks and protocols, including PSTN, ISDN, wireless network, all LAN protocols, asynchronous transmission mode ATM, and so on, and allow applications to control the reliability, redundancy, and bandwidth of established connections. Therefore, having mastered WinSock programming means having mastered a key for network programming in windows.
Specification for enabling network programming in Windows-Windows Sockets. This specification is a network programming interface that is widely used and open in windows and supports multiple protocols.
The Windows Sockets Specification defines and records how to use APIs to connect to the Internet protocol family (IPs, usually tc p/IP, in particular, all Windows Sockets implementations support streaming and datagram interfaces.
Applications call the Windows Sockets API to communicate with each other. Windows Sockets uses the lower-layer network communication protocol function and operating system call to realize the actual communication work. 1.

Figure 1 Relationship between applications and Windows Sockets

Ii. Two socket forms

A socket is an abstraction of a communication endpoint. It provides a mechanism for sending and receiving data. In a Windows Socket, [1]. It has two forms: datagram socket and stream socket ). the stream socket uses the transmission control protocol TCP, which provides bidirectional, ordered, non-repetitive, and non-record-free data stream services. In this mode, A virtual connection must be established between two communication applications. The stream mode features reliable communication and a data verification and re-transmission mechanism, it is usually used for transmission of data files, such as FTP and telnet, and is suitable for transmission of large amounts of data.
The datagram set interface uses the User Datagram Protocol UDP. It is built on the IP protocol and provides connectionless datagram transmission to support two-way data streams, but it is not guaranteed to be reliable and orderly, no duplicates and. That is to say, a process receiving information from the datagram set interface may find that the information is duplicated, or it is different from the sending order. An important feature of the datagram set interface is its record boundary. For this feature, the datagram set interface uses a model that is very similar to many packet switching networks (such as Ethernet, due to the cancellation of the re-sending verification mechanism, the data packet method can achieve a high communication rate and can be used for some communications that do not require high data reliability, such as real-time voice, image transfer, broadcast messages, etc.
Whether to use a streaming socket or a datagram socket has a great impact on communication efficiency. In programming, stream sockets and datagram sockets are different. In a streaming socket, the server first starts and creates an interface by calling socket. Then bind () is called to associate the set of interfaces with the local network address, and then listen () is called to prepare the set of interfaces for listening and specify the length of its request queue, then, the customer calls accept () to receive connections. After the customer establishes an interface, he can call connect () to establish a connection with the server. Once the connection is established, the client and the server can send and receive data by calling read () and write. Finally, after the data transfer is completed, both parties call clo Se () to close the set of interfaces. 3.

Figure 2 no connection set interface application time sequence diagram

Unlike streaming sockets, In a datagram socket, the server does not call accept (), and the client does not call connec T (). Before sending data, no complete correlation has been established between the client and the server. The unconnected server has established a local semi-correlation through socket () and bind. Before data transmission, the two unconnected endpoints have been established with a local socket number and a local socket address. Therefore, a complete correlation is dynamically established during the data sending and receiving process to enable non-connected customers and servers to identify each other. 2.

Figure 3 timing diagram of the application for the interface

3. Communication Selection Method

During network development, You must select whether to use the blocking mode or non-blocking mode.
In network communication, due to network congestion or the amount of data sent at a time is too large, data exchange may often fail to be transmitted in a short period of time. Therefore, functions for sending and receiving data cannot be returned, this phenomenon is called blocking. Winsock provides two Processing Methods for functions that may be blocked: blocking and non-blocking.
In the blocking mode (also known as synchronous mode), the function that sends and receives data is called until the transfer is completed or an error occurs before it can be returned. The operation may take any long time to complete. The problem arises. The most obvious example is Recv (). This function will remain congested until it receives the data sent by the other system.
For non-blocking mode, the function is returned immediately after it is called. After the transfer is complete, Winsock sends an agreed message to the program.
In the Berkeley set interface model, the default behavior of an interface set operation is blocking mode, unless the programmer explicitly requests this operation as a non-blocking mode. Microsoft strongly recommends that programmers use non-blocking (asynchronous) operations whenever possible. Therefore, non-blocking operations can work better in non-dominant Windows environments. programmers should use blocking when absolutely necessary.
If a process running a blocking operation receives a Windows message, the application may try to send another Windows Sockets call because it is difficult to handle this situation safely, windows Sockets does not support the way this application works. In this case, there are two functions that can help programmers. Wsaisblocking () can be used to determine whether there is a blocked Windows Sockets call on the process. Wsacancelblookingcall () can be used to cancel online blocking calls, if any. If any other Windows Sockets function is called in this case, it will fail and return the error code wsaeinprogress. It should be emphasized that this restriction applies to all blocking and non-blocking operations. To avoid the disadvantage of blocking operations, we can use multi-threaded programming.
Winsock implements non-blocking communication through the asynchronous selection function wsaasyncselect. When a specified network event occurs, the Winsock sends messages agreed by the program in advance to the program. The program can process the messages accordingly. The format is as follows:
Int wsaasyncselect (socket S, hwnd, unsigned int wmsg, long Levent) sockets is automatically set to a non-blocking mode in this function call. hwnd is the window handle for receiving Winsock messages, in non-blocking mode, wmsg is the name of the message sent to the window. You can define it as needed. Levent is a specified network event and has the following options:
  .The FD-READ wants to receive a message when the socket receives the data;
  .The FD-WRITE receives a message when it can send data;
  .The FD-ACCEPT receives a message when a connection request arrives;
  .The FD-CONNECT receives a message when the connection is successful;
  .Message received by the FD-CLOSE when the link is closed.
When a specified event occurs, the program receives the message. In the MSG structure of the message, the message item is the specified message name wmsg, the content in the lparam item is exactly the same as the above network cable event name. One thing to note is that in the non-blocking status, the return values of the Connect () function are socket-error, indicating that it may not be able to establish a connection with the remote server. To distinguish this situation from other errors, you can call a special function wsagetlasterro R () to check the cause of socket-error, if the return value of this function is wsaewouldblock, it indicates the above situation. At this time, the program can give the user a prompt, indicating that the program is trying to establish a connection with the remote server, if the waiting time is too long, the user can stop it.

Iv. Introduction to multithreading technology

When the data transmitted over the network is large data blocks, blocking often occurs. To avoid this situation and improve transmission efficiency, we can use multithreading for network programming.
The 32-bit windows Win32 API provides interface functions for developing multi-threaded applications, and the Standard C library provided by VC ++ 6.0 can also develop multi-threaded applications, however, it is more common to use the MFC class library for multi-threaded programming. Mf c executes two types of threads: worker thread and user-int erface thread ). Both types use the same Win32 API call mechanism, And the cwinthread class provided by the visual C ++ 6.0 MFC Library is the basis for multithreading programming. In fact, the cwinapp class is a user interface thread, which is derived from the cwinthread class and used for interaction between applications and users.
There are two ways to create a thread. MFC provides the following global function creation thread: afxbeginthread (). afxbeg I nthread () can be used to create a thread. MFC provides two versions of afxbeginthread () it is used to create worker threads and user interface threads respectively. This function creates a thread object and returns a pointer to the object (this pointer can be used to accomplish what you want to do ). In addition, you can also create a thread object explicitly. You need to declare the thread object first, and then call the cwinthread member function cwinthread: Create therad () to create a thread, because MFC distinguishes two threads, the parameters for creating threads are also different. It is precisely because different parameters distinguish different threads. This will be detailed in the following with so ckets programming.

5. Develop a socket program with multiple threads in vc6.0

In actual programming, we generally use object-oriented technology, especially the message-driven mechanism to implement multi-task windows programming ideas. VC is widely used due to its powerful functions.
1. Basic steps for developing a socket program using vc6.0
In VC ++ 6.0, we can use the Windows Sockets API to write network programs. More commonly, we use the casyncsocket and csocket classes encapsulated by MFC for network programming, it converts Windows messages related to sockets into callback functions. Compared with csocket, casyncsocket is more open to lower layers and flexible to use, but it also has high requirements for programmers, you need to know more about the network. Csocket is the export class of casyncsocket. It provides high-level abstraction through the carchive class objects in MFC. It encapsulates many details in socket implementation and combines socke T with archive, it is similar to the document serialization protocol in MFC, which is easy to use. Generally, we use simple csocket programming. The steps are as follows:
(1) construct a socket object. (2) Use this object to construct a basic socket. For a csocket client object, use the default create parameter. For a csocket Server Object, specify a port number as a parameter of greate, used for monitoring. (3) Establish a client csocket and call casyncsocket: connect to establish a connection with the server, the server socket calls casyncsocket: Listen listener, and call casyncsocket: After receiving the client request :: acce pt. (4) construct the csocketfile object and associate the csocket object with it. (5) construct a carchive object for receiving or sending data. (6) use the carchive object for socket communication between the client and the server. (7) delete carchive, C socketfile, and csocket objects. Flowchart 4:

   

Figure 4 Procedure of Using VC to establish socket communication between the client and server

2. Use of callback Functions
To facilitate network communication, casyncsocket and csocket provide some callback functions. The main window calls these callback functions to handle important socket events. These callback functions include onreceive, onsend, onconne CT, onaccept, and onclose, which can be obtained through reload in two classes. These two classes only Use callback functions to convert messages into notifications. We must implement them ourselves to respond to these notifications.
Void crecesocket: onreceive (INT nerrorcode)
}
Casyncsocket: onreceive (nerrorcode );
Receive (lpbuf, int nbuflen, int nflage = 0)
}
If your class inherits casyncsocket, you must reload these callback functions to make communication more convenient. If your class inherits csocket, you can decide whether to reload them as needed. It must be noted that the csocket object never calls the onsend onconnect notification functions, but can only call the send function to send data until the sending is complete and there is a data send to return, similarly, you can only call the connect function for connection. When the connection is completed (successful or failed), con nect will return.
3. Use multithreading to develop network communication
The default blocking method of the csocket class. To avoid blocking disadvantages, you can use multiple threads to process data receiving and sending in a work thread, which can be run in the background, the blocking of sockets in the working thread does not affect other activities in the main thread, so that the main thread can process message ing in the main window, the following example describes how to create and execute a socket working thread. This thread creates a socket and connects to the server (IP Address: 202.194.20.250, send some data to the server after the connection is successful.
Uint socketproc (lpvoid pparam)
{
Csendview * pview = (csendview *) pparam;
Csocket * psocket = new csocket ();
Psocket-> Create (); // construct a csocket object
// Connect to the server
If (! Psocket-> connect ("202.194.20.250" 5050 ))
Afxmessagebox ("can" tconnect to the distines! ")
// Construct the csocketfile object and associate it with the csocket object.
Csocketfile * m-pfile = new csocketfile (psocket );
// Construct a carchive object for sending data.
Carchive * m-parchiveout = new carchive (m-pfile, carchive: Store)
If (m-parchiveout! = NULL)
}
// Send data. M-sockdata is a structure defined in the window class,
// PMSG is a pointer variable in this structure
Pview-> M-sockdata-> PMSG-> serialize (* m-parchiveout)
M-parchiveout-> flush ()
}
Else
Return O;
}
Use afxbeginthread (socketproc, pview) to execute the program where appropriate.
In addition to working threads, you can also use User Interface threads. the user interface thread adds message ing, which will be used in the following example.
The casyncsocket class should not be set as a blocking method to handle blocking problems, but should be asynchronous. In the asynchronous mode, the call will return immediately. Using the getlasterror function, the corresponding error code wsaewouldblock will be obtained, indicating that no connection is acceptable. For example, in the asynchronous mode, after the receive function is called, the error message of wsaewocould block will be obtained until the onreceive callback function is called to notify us that we can receive data again.
4. Pay attention to synchronization when using multithreading for socket programming
When using multithreading technology for network programming, you must pay attention to the synchronization of socket objects. You can use the thread synchronization mechanism to coordinate access to socket objects.
If an MFC window object is created in the thread, this MFC object cannot be used in other threads. That is, for socket programming, a socket object should be used only for a single thread, the socket object cannot be passed between two threads. For example, a server can normally accept multiple connections. Each time it accepts a connection, a thread is created to process the connection. To achieve this goal, it is not enough to pass socket objects in the two threads.
Although the socket object cannot be passed between two threads, we can pass the thread handle between threads. Therefore, we can:
(1) detach the socket handle on the socket object attached to the thread that accepts the connection.
(2) Pass the socket handle in two threads.
(3) append the socket handle to the socket object in the thread processing the socket connection.
To better illustrate the above method, we will list the parts of the program:
// Create the onaccept function of the listening thread in the main thread
Void clistensocket: onaccept (INT nerrorcode)
{
Casyncsocket SOC; // temporary object created for accepting connection requests
Accept (SOC); // receives the request
// Create and suspend a new thread (this thread is a user interface thread)
Csockthread * pthread = (csockthread *) afxbeginthread (
RUNTIME-CLASS (csockthread), thread-priority-normal.
O, create-susponded );
// Detach the socket handle from the socket object and save it
Pthread-> M-hsocket = (socket) Soc. Detach ();
// Start executing the new thread
Pthread-> resumethread ();
Casyncsocket: onaccept (nerrorcode );
}
// Process the initinstance function of the connection thread (New thread,
Bool csockthread: initinstance ()
// Append the socket handle to the new socket object,
// The notification function of the main thread can be sent to the new thread for processing in the new thread.
M-socket, attach (m-hsocket );
Return true;
}
Through the above steps, we can use multiple threads to process network communication.

Vi. Summary

During the development of the E-Classroom System, we use network programming to achieve continuous image transmission between the primary and student machines, and the transmission effect is quite satisfactory. We use casyncsocket and csocket to transmit images over the network. The effects of the two classes are almost the same, but because the csocket class can use carchive objects to transmit data, and the multi-thread technology is introduced for network communication to avoid blocking, the csocket class can fully meet the requirements of image communication.
Because the communication modules of client and server programs are network communication programs developed using sockets, the complex structure and protocols at the network layer are shielded so that application software can run on various networks, you don't have to worry about the network and the specific location and data transmission details of the server or client on the Internet.

 

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.