Reading this article requires readers to have at least a basic knowledge of C/C + + network programming and how to use the basic Socket API
At the same time, readers should have at least used cfadmin framework and be proficient in using built-in library to complete simple business logic writing
Students interested in this article can also Official website And file To learn more about how to use the framework
Read the preface
cfadmin is a high-performance server-side framework written by C and Lua. Although the current Web service is built in, it still needs to use the original socket
cfadmin encapsulates most socket APIs. Developers can only use the internally provided Lua interface without considering the C/C + + level
From this chapter, I will learn how to use cfadmin hidden widgets
quick get start
We create script/client.lua and script/server.lua files respectively in the script directory, and write the following contents:
-- script/server.lua local TCP = require "internal.TCP" local server = TCP:new() server:listen("127.0.0.1", 8080, function (fd, ip, port) local sock = TCP:new():set_fd(fd) print(fd, ip, port) sock:close() end)
-- script/client.lua local TCP = require "internal.TCP" local client = TCP:new() assert(client:connect("127.0.0.1", 8080)) print("Connection succeeded.") client:close()
Then, we open two terminals to run them:
root@server:~/cfadmin$ ./cfadmin -e script/server.lua 8 ::ffff:127.0.0.1 15504
root@server:~/cfadmin$ ./cfadmin -e script/client.lua Connection succeeded.
If we close the server process first and only run the client process, we will get the following prompt:
root@server:~/cfadmin$ ./cfadmin -e script/client.lua [2021/11/11 17:11:50] [coroutine error] script/client.lua:6: Connection refused stack traceback: script/client.lua:6: in main chunk
You're right. We can easily locate where the code went wrong
Code parsing
What makes it so easy for us to complete the network connection? Now let's go back to the previous code:
-- script/server.lua local TCP = require "internal.TCP" local server = TCP:new() server:listen("127.0.0.1", 8080, function (fd, ip, port) local sock = TCP:new():set_fd(fd) print(fd, ip, port) sock:close() end)
-- script/client.lua local TCP = require "internal.TCP" local client = TCP:new() assert(client:connect("127.0.0.1", 8080)) print("Connection succeeded.") client:close()
First, we import the TCP library into the client and server, and then create the required TCP Socket instances for each
Instances can be used to complete various network operations, such as send, sendfile, recv, readline, close, etc
But before these operations, we must first complete listen and connect! These 2 methods must be invoked before other network operations.
Therefore, we start to call the listen and connect methods on line 5, so that the basic operations on both sides are finished
1. listen(ip, port, callback)
The listen method has three required parameters:
-
ip - String type, which can specify the address to listen to;
-
port - Integer type, which specifies the port used to listen;
-
callback - Function type. The successfully connected client will trigger a callback;
The callback function prototype of callback is: function (fd, ip, port) end
-
fd - Integer type, file descriptor;
-
ip - String type, client connection address;
-
port - Integer type, client connection port;
The callback function will be injected with the above parameters, which will help you understand the source of the client
2. connect(ip, port)
The connect method has 2 required parameters:
-
ip - String type, which can specify the address to listen to;
-
port - Integer type, which specifies the port used to listen;
Return true for success, false for failure, and the error reason of string type
3. Blocking and non blocking
The server callback triggered by each connection establishment will create a workflow. Each workflow is a separate execution stack and independent of each other
Assuming that two links A and B are created and established at the same time, they will run in their respective processes, and A's Read will not affect B's Write
Because coprocessor and event driven realize real synchronization and non blocking, we can write asynchronous code in a synchronous way
4. Working mode
Note: Socket can only work in half duplex mode by default! As for why it is designed like this, we will discuss it in a subsequent article
5. Resource recovery
Each time the server accepts a new connection, it must create an object to manage the file descriptor. It is also the corresponding system allocated file descriptor
Lua's GC can't help me reasonably release fd resources, so we must actively close to release resources after use
last
In this chapter, we have learned the basic network application programming method of cfadmin. In the next chapter, we will learn how to write network applications for interaction