structmg_addr { uint16_t port; // TCP or UDP port in network byte order uint32_t ip; // IP address in network byte order uint8_t ip6[16]; // IPv6 address bool is_ip6; // True when address is IPv6 address };
struct mg_mgr
简介:
它是一个事件管理结构体,能够保存一个正在活动的连接列表,以及一些维持管理的信息
原型
1 2 3 4 5 6 7 8
structmg_mgr { structmg_connection *conns;// List of active connections 结构体数组 structmg_dnsdns4;// DNS for IPv4 structmg_dnsdns6;// DNS for IPv6 int dnstimeout; // DNS resolve timeout in milliseconds unsignedlong nextid; // Next connection ID void *userdata; // Arbitrary user data pointer };
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { if (ev == MG_EV_OPEN) { ... // Do your initialisation }
如果您需要保留一些特定连接的数据,则有两个选择
第一,使用c->fn_data指针。该指针作为最后一个参数传递给事件处理程序
1 2 3 4 5 6 7 8 9 10 11 12
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { if (ev == MG_EV_OPEN) { c->fn_data = malloc(123); // Change our fn_data } else if (ev == MG_EV_CLOSE) { free(fn_data); // Don't forget to free! } ... }
// Every accepted connection inherit NULL pointer as c->fn_data, but we change // it per-connection to something else mg_http_listen(&mgr, "http://localhost:1234", fn, NULL);
第二,使用c->label缓冲区。该缓冲区可以容纳一些特定于连接的数据,而无需额外的内存分配
1 2 3 4
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { if (ev == MG_EV_WS_OPEN) { c->label[0] = 'W'; // Established websocket connection, store something ...
struct mg_addr { uint16_t port; // TCP or UDP port in network byte order uint32_t ip; // IP address in network byte order uint8_t ip6[16]; // IPv6 address bool is_ip6; // True when address is IPv6 address };
该结构包含网络地址。它可以被认为sockaddr结构在Mongoose中的等价结构体
struct mg_mgr
1 2 3 4 5 6 7 8
struct mg_mgr { struct mg_connection *conns; // List of active connections 结构体数组 struct mg_dns dns4; // DNS for IPv4 struct mg_dns dns6; // DNS for IPv6 int dnstimeout; // DNS resolve timeout in milliseconds unsigned long nextid; // Next connection ID void *userdata; // Arbitrary user data pointer };
struct mg_http_serve_opts { const char *root_dir; // Web root directory, must be non-NULL const char *ssi_pattern; // SSI file name pattern, e.g. #.shtml const char *extra_headers; // Extra HTTP headers to add in responses const char *mime_types; // Extra mime types, ext1=type1,ext2=type2,.. const char *page404; // Path to the 404 page, or NULL by default struct mg_fs *fs; // Filesystem implementation. Use NULL for POSIX };
buf – 一个url编码的字符串:HTTP请求体或查询字符串(HTTP request body or query string)
name – 获取的变量名字
返回值:返回变量的值 或 返回一个空的字符串,表示没有找到
示例:
1 2 3
// We have received a request to /my/uri?a=b&c=d%20 // The hm->query points to "a=b&c=d%20" struct mg_str v = mg_http_var(hm->query, mg_str("c")); // v = "d%20"
mg_http_get_var()
int mg_http_get_var(const struct mg_str *var, const char *name, char *buf, int len);
获取并解码HTTP 变量
参数:
var – HTTP请求体(HTTP request body)
name – 变量名
buf – 写入解码变量的缓冲区(Buffer to write decoded variable)
mg_http_printf_chunk(c, "&customer=%s", customer_id); // Set customer mg_http_printf_chunk(c, "&items[0][price]=%s", price); // And price mg_http_printf_chunk(c, ""); // End request
struct mg_http_part
声明:
1 2 3 4 5 6
// Parameter for mg_http_next_multipart struct mg_http_part { struct mg_str name; // Form field name struct mg_str filename; // Filename for file uploads struct mg_str body; // Part contents };
这是一个助手实用程序功能,用于通过小块上传大型文件。将HTTP POST 数据追加到指定目录的文件中。文件名和文件偏移由查询字符串参数指定:POST /upload?name=firmware.bin&offset=2048 HTTP/1.1。如果偏移量为0,则将文件截断。客户的责任是将文件分为较小的块,并发送一系列由此功能处理的POST请求
// Mongoose events handler void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { if (ev == MG_EV_WS_MSG) { struct mg_ws_message *wm = (struct mg_ws_message *) ev_data; msgtype = wm->flags & 0x0F; if (msgtype == WEBSOCKET_OP_BINARY) { // This is a binary data message } else if (msgtype == WEBSOCKET_OP_TEXT) { // This is a text data message } } }
// Assume that hm->uri holds /foo/bar. Then we can match the requested URI: struct mg_str caps[3]; // Two wildcard symbols '*' plus 1 if (mg_match(hm->uri, mg_str("/*/*"), caps)) { // caps[0] holds `foo`, caps[1] holds `bar`. }
struct mg_str k, v, s = mg_str("a=333,b=777"); while (mg_commalist(&s, &k, &v)) // This loop output: printf("[%.*s] set to [%.*s]\n", // [a] set to [333] (int) k.len, k.ptr, (int) v.len, v.ptr); // [b] set to [777]
// Printing sub-function for %M specifier. Grabs two int parameters size_t f(void (*out)(char, void *), void *ptr, va_list *ap) { int a = va_arg(*ap, int); int b = va_arg(*ap, int); return mg_xprintf(out, ptr, "%d", a + b); }
bool b = false; mg_json_get_bool(mg_str("[123]", "$[0]", &b)); // Error. b remains to be false mg_json_get_bool(mg_str("[true]", "$[0]", &b)); // b is true
mg_json_get_long()
long mg_json_get_long(struct mg_str json, const char *path, long default_val);
在JSON路径path,从json字符串获取数字值(long)。
参数:
json – 保存有效JSON字符串
path – 一个JSON路径。必须以$开始
v – 一个对应于值的占位符
返回值:
返回找到的值
返回default_val值
示例:
1 2
long a = mg_json_get_long(mg_str("[123]", "$a", -1)); // a = -1 long b = mg_json_get_long(mg_str("[123]", "$[0]", -1)); // b = 123
结构代表HTTP标头,像Content-Type: text/html。Content-Type 是一个 Header name,text/html/是一个 Header value
原型
1 2 3 4
structmg_http_header { structmg_strname;// Header name structmg_strvalue;// Header value };
struct mg_http_message
简介:
结构代表HTTP消息。
原型
1 2 3 4 5 6
structmg_http_message { structmg_strmethod, uri, query, proto;// Request/response line structmg_http_headerheaders[MG_MAX_HTTP_HEADERS];// Headers structmg_strbody;// Body structmg_strmessage;// Request line + headers + body };
structmg_http_serve_opts { constchar *root_dir; // Web root directory, must be non-NULL constchar *ssi_pattern; // SSI file name pattern, e.g. #.shtml constchar *extra_headers; // Extra HTTP headers to add in responses constchar *mime_types; // Extra mime types, ext1=type1,ext2=type2,.. constchar *page404; // Path to the 404 page, or NULL by default structmg_fs *fs;// Filesystem implementation. Use NULL for POSIX };
buf : 一个url编码的字符串:HTTP请求体或查询字符串(HTTP request body or query string)
name : 获取的变量名字
返回值:
成功,返回变量的值
失败,返回一个空字符串
示例:
1 2 3
// We have received a request to /my/uri?a=b&c=d%20 // The hm->query points to "a=b&c=d%20" structmg_strv = mg_http_var(hm->query, mg_str("c")); // v = "d%20"
mg_http_get_var
简介:
获取并解码HTTP 变量
原型:
1
intmg_http_get_var(conststruct mg_str *var, constchar *name, char *buf, int len);
参数:
var : HTTP请求体(HTTP request body)
name : 变量名
buf : 写入解码变量的缓冲区(Buffer to write decoded variable)
// Mongoose events handler voidfn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { if (ev == MG_EV_HTTP_MSG) { structmg_http_message *hm = (struct mg_http_message *) ev_data; char user[100], pass[100]; mg_http_creds(hm, user, sizeof(user), pass, sizeof(pass)); // "user" is now user name and "pass" is now password from request } }
mg_http_printf_chunk(c, "&customer=%s", customer_id); // Set customer mg_http_printf_chunk(c, "&items[0][price]=%s", price); // And price mg_http_printf_chunk(c, ""); // End request
struct mg_http_part
简介:
描述HTTP 多个消息(multipart message)中单个部分的结构体
原型:
1 2 3 4 5 6
// Parameter for mg_http_next_multipart structmg_http_part { structmg_strname;// Form field name structmg_strfilename;// Filename for file uploads structmg_strbody;// Part contents };
while ((pos = mg_http_next_multipart(body, pos, &part)) != 0) { // Use part }
mg_http_upload
简介:
这是一个助手实用程序功能,用于通过小块上传大型文件。将HTTP POST 数据追加到指定目录的文件中。文件名和文件偏移由查询字符串参数指定:POST /upload?name=firmware.bin&offset=2048 HTTP/1.1。如果偏移量为0,则将文件截断。客户的责任是将文件分为较小的块,并发送一系列由此功能处理的POST请求
structmg_iobuf { unsignedchar *buf; // Pointer to stored data size_t size; // Total size available size_t len; // Current number of bytes size_t align; // Alignment during allocation };
structmg_rpc_req { structmg_rpc **head; // RPC handlers list head structmg_rpc *rpc; // RPC handler being called mg_pfn_t pfn; // Response printing function void *pfn_data; // Response printing function data void *req_data; // Arbitrary request data structmg_str frame; // Request, e.g. {"id":1,"method":"add","params":[1,2]} };
// Time to cleanup mg_rpc_del(&s_rpc_head, rpc_mul); // Deallocate specific handler mg_rpc_del(&s_rpc_head, NULL); // Deallocate all RPC handlers
mg_rpc_process
简介:
为这个请求调用合适的方法。如果请求的方法不存在,将调用mg_rpc_err()并打印错误提示。
原型:
1
voidmg_rpc_process(struct mg_rpc_req *req);
参数:
req – 一个请求
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
structmg_rpc *s_rpcs = NULL; // Empty RPC list head mg_rpc_add(&s_rpcs, mg_str("rpc.list"), mg_rpc_list, NULL); // Add rpc.list // ... add more RPC methods
// On request, process the incoming frame structmg_str req = mg_str("{\"id\":1,\"method\":\"sum\",\"params\":[1,2]}"); structmg_iobuf io = {0, 0, 0, 512}; // Empty IO buf, with 512 realloc granularity structmg_rpc_req r = { .head = &s_rpcs, // RPC list head .rpc = NULL, // This will be set by mg_rpc_process() .pfn = mg_pfn_iobuf, // Printing function: print into the io buffer .pfn_data = &io, // Pass our io buffer as a parameter .req_data = NULL, // No specific request data .frame = req, // Specify incoming frame };
structmg_timer { uint64_t period_ms; // Timer period in milliseconds uint64_t expire; // Expiration timestamp in milliseconds unsigned flags; // Possible flags values below #define MG_TIMER_ONCE 0 // Call function once #define MG_TIMER_REPEAT 1 // Call function periodically #define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set void (*fn)(void *); // Function to call void *arg; // Function argument structmg_timer *next;// Linkage };
structmg_tls_opts { constchar *ca; // CA certificate file. For both listeners and clients constchar *crl; // Certificate Revocation List. For clients constchar *cert; // Certificate constchar *certkey; // Certificate key constchar *ciphers; // Cipher list structmg_str srvname; // If not empty, enables server name verification structmg_fs *fs; // FS API for reading certificate files };
参数:
ca – 证书颁发机构。可以是文件名或字符串。用于验证另一端发送给我们的证书。如果为空,则禁用证书检查。
// Mongoose events handler voidfn(struct mg_connection *c, int ev, void *ev_data, void *fn_data){ if (ev == MG_EV_WS_MSG) { structmg_ws_message *wm = (struct mg_ws_message *) ev_data; msgtype = wm->flags & 0x0F; if (msgtype == WEBSOCKET_OP_BINARY) { // This is a binary data message } elseif (msgtype == WEBSOCKET_OP_TEXT) { // This is a text data message } } }
-rw-r--r-- 1 user group 250 Apr 10 10:00 file10.txt -rw-r--r-- 1 user group 200 Apr 10 10:00 file2.txt -rw-r--r-- 1 user group 150 Apr 10 10:00 fileA.txt -rw-r--r-- 1 user group 100 Apr 10 10:00 file1.txt -rw-r--r-- 1 user group 50 Apr 10 10:00 fileB.txt
总结
通过结合使用 ls 命令的不同选项以及 sort 命令,你可以根据各种规则对目录下的文件进行排序。选择适合你需求的命令和选项,并根据需要进行调整。
shell 字符串分割
在 Shell 中,可以使用多种方法来分割字符串。下面是几种常见的方法:
1. 使用 IFS(内部字段分隔符)
使用 IFS 变量可以轻松地将字符串分割成数组。以下是一个示例,将逗号分隔的字符串分割成数组:
1 2 3 4 5 6 7 8 9 10
#!/bin/bash
str="apple,banana,cherry" IFS=','read -r -a array <<< "$str"
# 输出数组元素 for element in"${array[@]}" do echo"$element" done
gsettings set org.gnome.system.proxy mode 'manual' gsettings set org.gnome.system.proxy.http host 'proxy.example.com' gsettings set org.gnome.system.proxy.http port 8080