I believe that many people are interested in network programming. Let's introduce the most widely used programming interface Winsock API in network programming.
Use the Winsock API programming, you should learn about the basics of TCP / IP. Although you can use the Winsock API to write a web application, but you must write an excellent web application or you must have some understanding of the TCP / IP protocol.
1. The relationship between TCP / IP protocol and Winsock network programming interface
Before you start, let's talk about what Winsock and TCP / IP do.
I met a lot of people asked me: How to use Winsock protocol programming? In fact, this is a bit wrong. Winsock is not a network protocol. He is just a network programming interface, that is, he is not an agreement, but he can visit many kind of network protocol, you can treat him as some agreement. . The current Winsock has basically implemented unrelated to the agreement. You can use Winsock to call the functions of multiple protocols.
So what is the relationship between Winsock and TCP / IP protocols? In fact, Winsock is a package of TCP / IP protocol. You can call various functions of TCP / IP by calling Winsock interface functions. For example, I want to send data with TCP / IP protocol, you can use Winsock interface The function send () calls the transmission data function of TCP / IP, as for how to send data, Winsock has helped you package this feature.
2, TCP / IP protocol introduction
Now introduce some principles of TCP / IP. The TCP / IP protocol contains very wide range, and he is a four-layer agreement that includes a variety of hardware, software requirements, and we only introduce software knowledge here. The TCP / IP protocol should be the TCP / UDP / IP protocol.
The UDP protocol (User DataGram Protocol User Data News Agreement) is a transmission of message boundaries and does not guarantee the transmission of reliable data.
TCP Agreement (Transmission Control Protocol Transmission Control Protocol) is a protocol for streaming. He offers reliable, orderly, two-way, facing-oriented transmission.
3, protect message boundaries and streams
So what is the protection of the message boundary and stream?
Protect the message boundary, means that the transfer protocol uses the data as a separate message to transmit online, and the receiving end can only receive independent messages. That is to say, there is a protection message boundary, and the receiving end can only receive a packet issued by the sender.
The flow-oriented is to refer to the boundary without the protection message protection. If the sender continuously transmits the data, the receiving end may receive two or more packets in one reception operation.
We will give examples, for example, we have sent three packets, the size is 2K, 4K, 8K, and these three packets have reached the network stack of the receiving end. If you use the UDP protocol, no matter how big us The receiving buffer to receive data, we must have three reception actions to receive all packets. Use the TCP protocol, we only need to set the received buffer size above 14K, we can receive all packets once, only one receive action is required.
This is because the NDP protocol's protection message boundary makes each message independent. The flow transfer, but treats the data as a string of data, he doesn't think the data is a message. Therefore, many people are using TCP protocol communication, and the TCP is not clear-based transmission. When continuous transmission of data, they often know TCP will lose. In fact, because when they use the buffer enough, they may receive two or more packets at a time, and many people tend to ignore this, only analyze the first packet, and Other uses that have been received are ignored. So everyone must pay attention to this when they want to make such a network programming. 4, Winsock programming simple process
Let's introduce the WINSOCK programming method of the Win32 platform.
Communication must have server-side and clients. We briefly introduce the general process of the TCP server.
For any Winsock-based programming first we must initialize the Winsock DLL library.
INT WSASTARUP (Word WversionRequested, LPWSADATA LPWSADATA).
WVersionRequested is the version of Winsock we request.
Calling this interface function can help us initialize Winsock. Then we have to create a socket.
Socket Socket (int AF, INT TYPE, INT Protocol);
Sockets can be said to be the core of Winsock Communications. All data transfer of Winsock Communications is completed by sockets. The socket contains two information, one is an IP address, one is the port number, use these two information, we can determine the network Any communication node.
When we call the socket () interface function created a socket, we must connect the socket with the address you need to communicate, we can implement this connection through the binding function.
INT Bind (Socket S, Const Struct Sockaddr Far * Name, Int Namelen);
Struct sockaddr_in {
Short sin_family;
U_SHORT SIN_PROT;
Struct in_addr sin_addr;
Char Sin_Sero [8];
}
The local address we need to establish a connection, including address family, IP, and port information. SIN_FAMILY field We must set him to AF_INET, which tells Winsock to use IP address family. SIN_PROT is the port number we want to communicate with. SIN_ADDR is the IP address information we want to communicate with.
Here, you must have to mention the 'head-endian' '. Because a variety of different computer processing data is different, the Intel X86 processor is used in the form of a multi-byte number on the form of the "smallhead '", which is to put the low byte in front and put high byte. In the back, the Internet standard is just the opposite, so we must convert the host byte into the order of network bytes. The Winsock API provides several functions.
Transform host bytes into a network byte function;
U_long htonl (u_long hostlong);
U_SHORT HTONS (u_short hostshst);
Transform the network byte into a host byte;
U_long ntohl; u_long netlong);
U_SHORT NTOHS (U_SHORT NETSHORT);
In this way, when we set the IP address and PORT port, we must use the bind () function to bind the socket and address with the bind () function to be used to translate the host byte into a network byte.
When the bind is completed, the server side must establish a listener queue to receive the client's connection request.
INT Listen (Socket S, INT Backlog); this function can turn our socket into monitor mode.
If the client has a connection request, we must also use
INT Accept (Socket S, Struct Sockaddr Far * Addr, Int Far * Addrlen);
To accept the request of the client.
Now we have completed the establishment of a server, and the process of the client's establishment is to initialize Winsock, then create a Socket socket, and then use
INT Connect (Socket S, Const Struct Sockaddr Far * Name, Int Namelen);
To connect the server.
Below is an example of the simplest creation server side and client:
Server-ended creation:
WSADATA WSD;
Socket slisten;
Socket sclient;
UINT port = 800;
INT Iaddrsize;
Struct SockAddr_in local, client;
WSASTARTUP (0x11, & WSD);
SListen = Socket (AF_INET, SOCK_STREAM, IPPOTO_IP);
Local.sin_family = af_INet;
Local.sin_addr = HTONL (INADDR_Any);
Local.sin_Port = HTONS (port);
Bind (SLISTEN, STRUCKADDR *) & local, sizeof (local));
Listen (Slisten, 5);
SCLIENT = Accept (Slisten, (Struct SockAddr *) & Client, & Iaddrsize
Creation of the client:
WSADATA WSD;
Socket sclient;
UINT port = 800;
Char Szip [] = "127.0.0.1";
INT Iaddrsize;
Struct SockAddr_in Server;
WSASTARTUP (0x11, & WSD);
SCLIENT = Socket (AF_INET, SOCK_STREAM, IPPOTO_IP);
Server.sin_family = af_INet;
Server.sin_addr = inet_addr (szip);
Server.sin_port = htons (port);
Connect (SCLIENT, STRUCT SOCKADDR *) & Server, SIZEOF (Server));
Once the server is connected and the client is established, whether it is the client or the server, it can be used.
Int Serad (Socket S, Const Char Far * BUF, INT LEN, INT FLAGS);
Int Recv (Socket S, CHAR FAR * BUF, INT LEN, INT FLAGS);
The function is to receive and send data because the TCP connection is two-way.
When you want to turn off the communication, you can call any side.
Int shutdown (socket s, int how);
To turn off the specified function of the socket. Repart
INT CloseSocket (Socket S);
To turn off the socket handle. Such a communication process is completed.
Note: The above code does not have any check function return value, if you do network programming, you must check the result of any WinSock API function, because many times the function call is not necessarily successful. The function described above, the return value type is int, if the function call fails, the return is Socket_ERROR. 5, Winsock programming model
The method described above is just the simplest Winsock communication, and many network communication has many unexpected accidents.
For example, Winsock provides two socket modes: locking and non-locking. When we use lock sockets, we use a lot of functions, such as Accpet, Send, Recv, etc. If there is no data need to be processed, these functions will not return, that is, your application will block those The call to the function. And if you use a non-blocking mode, call these functions, no matter if you have data arrive, he will return. So it is possible that we will return to failure in the non-blocking mode, and will return to fail, so we need to handle many accidents.
This is obviously not what we want to see. We can use Winsock's communication model to avoid these conditions.
Winsock provides five socket I / O models to solve these problems. They are select, WSaasyncselect (Asynchronous Selection), WSAEventselect (Event Selection, Overlapped, Completion Port).
We will introduce the two models of SELECT, WSAASYNCSELECT here.
The SELECT model is the most common I / O model.
use
Int Select (int NFDS, FD_SET FAR * READFDS, FD_SET FAR * WRITEFDS, FD_SET FAR * EXCEPTFDS, CONST STRUCT TIMEVAL FAR * TIMEOUT);
The function is checked whether the Socket socket you want to call has a data that needs to be processed.
SELECT contains three Socket queues, representative:
ReadFDS, check readability, WriteFDs, check, ExceptFDs, exception data.
Timeout is the return time of the SELECT function.
For example, we want to check if a socket has data needs to be received, we can add a socket handle to the readability check queue, then call Select, if the socket does not receive the data, the SELECT function will put This socket is removed from the readability check queue, so we can know if the socket handle is still exhibited in the readability queue, you can know that there is no data to be received.
Winsock provides some macros to operate the socket queue fd_set.
FD_CLR (S, * SET) deletes the handle S from the queue set.
FD_ISSET (S, * SET) Check if the handle S exists in the queue set.
FD_SET (S, * SET) Adds the handle S to the queue set.
FD_ZERO (* SET) initializes the SET queue into an air queue.
WSaasyncselect (Asynchronous Selection) model:
The WSAAsyncselect model is to establish a window and a socket handle. When the network event of the socket occurs, it will send a message to the window, and then can process the data reception and send in the window message response function. .
INT WSAASYNCSELECT (Socket S, HWND HWND, UNSIGNED INT WMSG, Long Levent);
This function can connect the socket handle and the window.
WMSG is a message we must customize. LEVENT is a developed network event. Includes FD_READ, FD_WRITE, FD_ACCEPT, FD_CONNECT, FD_CLOSE.
Several events.
For example, I need to receive FD_READ, FD_WRITE, FD_CLOSE network events. Can be called
WSaasyncselect (s, hwnd, wm_socket, fd_read | fd_write | fd_close);
This way, when there is an FD_READ, FD_WRITE, or FD_CLOSE network event, window hWnd will receive a WM_Socket message, and the LPARAM flag of message parameters is what event occurs.
In fact, everyone should have seen this model because the MFC's CSocket class is to use this model.
The above introduces some methods of Winsock programming. Of course, Winsock programming is far more than this knowledge. If you want to learn online programming, you still need constant learning and research.