the 18th chapter the realization of socket class
Do you think over the past few days whether it's from top to bottom or from the bottom up? Finally, it is decided to start from the superstructure. The APO quest is simple and simple! Powerful and powerful! High speed, high efficiency! "The World Martial arts, no hard to break, only fast not broken!" ”。
APO's socket is also a memory file, but the socket descriptor and other types of file descriptors are slightly different. A user process in APO can open up to 64K non-socket file descriptors, while the APO system can only open up to 16M v nodes, requires 256 64K bits of bitmap variable, just 1 bitmap variable data blocks; mode management. The socket descriptor is also allocated in 16M file descriptors, the socket descriptor in APO, the description of a connection, can be said to be a connection number, and Unix may be a little different; in theory, APO can support up to 1千6百多万个 connections on a single service port. APO's network programming is very simple, such as the server-side program, just open a socket in the initialization method, the rest is just a variety of connection message processing method of writing. Even if there are 10 million connections, what can it do? Their request messages are handled the same way. Users do not have to care about how many socket descriptors are open, how many connections, closing connections, TCP/UDP, managing socket descriptors, and so on, which are the things that the user's system network processes. For the user's network programming, we just want to be as simple as possible. The service-side program only cares, comes a connection message with the request, needs to process the request message, use the socket descriptor in the message to manipulate the receive, or send stream container of the connection, as to how the connection is set up, whether there are currently 10 million connections, etc.
LINUX, Bind () in WinSocket, socket (), listen (), accept (), connect (), write (), read (), Recvfrom (), SendTo (), Upds_respon (), Recv (), Send (), recvmsg (), sendmsg (), Close, Shutdoen (), loop server, concurrent server, multiplexed I/O multiplexing, raw sockets, and so on, I see Dizzy, is this a library of network programming methods for application programmers? I can only sigh! It's rubbish! This is used by the underlying programmer, not the application programmer. Developed for several decades, should be the essence of condensed; Why do I always dislike? How does it feel to be so complicated and inefficient that smart people always complicate the problem? I also want to be compatible and adapt to them, but always powerless, I am stupid, unable to grasp their ideas. In any case, the server supports thousands of connected features I was set up, so that 1000 game servers can support 10 billion of people at the same time online.
In APO, network programming is divided into three layers: the first layer of the socket application layer, the second layer is the TCP/UDP (User CPU Line System Network Service process), the third layer is the lowest ip/icmp (kernel CPU line real-time thread). Between tiers is the use of message interaction, handle submission, and event-driven. The latter 2 layer is the system implementation, the user mainly uses the first layer programming. Socket is a kind of memory file, network programming is divided into server and client, network protocol is mainly TCP/UDP, in open file socket, need to specify. Open, Close is the basic method of file system, this article just describes the content of the socket. Datagram Receive is 2, 3 layer automatic implementation, contains the contents of the datagram handle is the corresponding socket file number SOCKFD, the message is submitted to the user process; The user only needs to use SOCKFD. The assignment instruction of the member, you can read and write the received datagram. Different file numbers SOCKFD handles, corresponding to different connections, and have different memory containers. As long as the local memory space is large enough to support thousands of connections there is no problem. Memory allocation is not necessary for the user to consider, as long as the planning on the line. Why? When we write a client program, it is not possible to know in advance what you request, the size of the datagram returned by the server, maybe 2GB, and it is impossible to declare the local memory size of the receiving stream container in the first place. However, after receiving the datagram returned by the server, the underlying is aware; therefore, it is possible to allocate memory from the underlying request and associate the handle to the corresponding SOCKFD. The reception does not seem to require user planning, but the request datagram you send can be preset size. If the client requests a 4GB size file, does the server need to apply for a contiguous 4GB size of memory space? User-written service-side program without such trouble, just send a message to Layer 2 (sendto ()), all 2 layers. Perhaps APO has 3 methods on the socket Layer: open (), close (), SendTo (). The first 2 is the basic method of the file system, the open () method has different parameters, so instead of opens (). The user program mainly writes the message processing, implements the HTTP protocol, the FTP and so on. In fact, even if these protocols are implemented, the APO operating system is included. The main user is to write the game and other service-side message processing bar.
When it is a client, the port of TCP/UDP can correspond to SOCKFD, process number, or thread number. However, it is not the same as the service side, although it can correspond to the process number, but there may be millions of connection, SOCKFD file number. Therefore, the server should set the flow label (Low 24 bits) = SOCKFD file Number (connection number), so that the next time the client with the same flow label (connection number) request arrives, the service side of the bottom of the server can quickly locate the corresponding Connection v node (of course, need to compare).
First, the service-side procedures
APO process is a message constant loop, user code entry main (); is to execute the process message processing code written by the user. We only need to process_init () in the initialization method of the common part of the process; Join in server-side mode, TCP or UDP, maximum number of connections backlog (256 connections), client-sent request message maximum length Recvlen (unit line e), the service side of the Send Flow container variable, the opens () method. So, the rest is the second layer of TCP/UDP, the user CPU line of the System Network service process of things. Whenever there is a new tcp/udp datagram that belongs to the service process, the second layer will raise the dynamic priority of the service process so that the service process can get the CPU faster, and send a message to the service process (including the connection number SOCKFD, the status code, and so on). When the service process obtains the CPU, there may already be n messages; 1, the system reads a message to the H2 Line register, the service process processes the message, 2, the judgment, if the second layer of System Network Service process issued, then is the network datagram message, with SOCKFD. Member, extract the datagram, analyze what is the request, Processes the request and finally sends back a server datagram. 3, loop back to 1, if there is no need to process the message, the service process concessions pending return. As for how to build a connection, there are millions of connections, memory allocations for datagrams, IP packet assembly, and so on; it is not the application layer to be concerned about, it is the underlying thing. So, APO's service-side program is out of the way, just a opens () and postback server datagram, possible sendto (which differs from Linux, Uinx, Windows), or closes a connection close (). Those, bind (), socket (), listen (), accept (), connect (), write (), read (), Recvfrom (), Upds_respon (), recv (), Send (), recvmsg () , Sendmsg (), Shutdoen (), Sigio, select () and so on, all clear; also apply the programmer a clean world. Note that if the same client sends a datagram, a datagram is sent when the service process has not finished processing, and the client is suppressed by traffic. If the previous datagram reaches above 1GB, the client will be immediately suppressed, not allowed to send datagrams, until the service process finishes processing the previous datagram. As for, hacker tracing, malicious TCP/UDP packet Judgment, connection processing, re-send timers, IP blacklist, attack alarm, packet filtering and so on are the underlying things, users do not have to pay attention. I know that UDP, possibly tens of millions of connectionsThe problem is not big, but TCP needs to be treated separately; that kind of timer is not good to deal with, should design tens of millions of timers? This is not possible;
Second, client-side programming
The user can set the client TCP/UDP program within a process, or thread. Still the 3 methods, but the parameters of the Opens method are set differently, nor are the initialization methods appearing; threads, or processes that open a connection opens, usually require the user to close the connection close.
Buxe SENDFV; In the main program, declare the Send Flow container.
thread_client () {//client methods, thread portals within threads.
sendfv.socketaddr_in =?;//Set the server-side IP address, port, etc. to be connected
sendfv.news =?;//Fill in the first message packet.
SOCKFD = Opens (FLAG. PORT, SENDFV);
//Get socket file number, Port = XX Client port specified, 0 specified by system;
//FLAG =0xa000 (TCP), 0x8000 (UDP), the second layer establishes a connection, and sends the first datagram.
PRET//Branch point waits for message, block return, new thread entry next instruction.
Msgpro ();//The datagram processing method returned by the server; message in H2, line assigns entry.
//Receive a server datagram, return a message from layer two to the corresponding process, and the process will start//
the corresponding thread Msgpro () method to handle.
If flag. Off flag = 1 then goto TCLT;
sendfv.news =?;//Fill in the message, or set the flag to fill in the Message pointer msg.
Sendto ();//A new request datagram is sent by the second layer.
Wret//wait for message, block return, prepare to process next datagram message.
TCLT:Close
(SOCKFD);//Closed Connection
Tret//thread termination return
third, opens () method
To be
continued ...
The 18th chapter the realization of Socket class