当前位置: 首页 > news >正文

网站跟app的区别网站建设的背景有哪些

网站跟app的区别,网站建设的背景有哪些,百度推广网址是多少,手机微网站怎么制作文章目录 前言一、结构体及其功能二、函数MG_LOGmg_http_listenmg_mgr_poll question参考链接 前言 mongoose是一款基于C/C的网络库#xff0c;可以实现TCP, UDP, HTTP, WebSocket, MQTT通讯。mongoose是的嵌入式网络程序更快、健壮#xff0c;易于实现。 mongoose只有mong… 文章目录 前言一、结构体及其功能二、函数MG_LOGmg_http_listenmg_mgr_poll question参考链接 前言 mongoose是一款基于C/C的网络库可以实现TCP, UDP, HTTP, WebSocket, MQTT通讯。mongoose是的嵌入式网络程序更快、健壮易于实现。 mongoose只有mongoose.c和mongoose.h两个文件其它的例子基本是基于这两个文件加上对应的xxx.c文件。mongoose.ws/documentation/介绍了mongoose.h文件中的API。 它通过单向链表维护所有连接的client对象其数据结构不是线程安全的。在httserver中该程序是单线成的通过epoll模式处理连接因此比较适合嵌入式等硬件资源有限的条件在不修改源码的情况下并发性能受限。 一、结构体及其功能 struct mg_mgr struct mg_mgr为时间管理结构体保存一系列的链接 conns指向单向链表的头部每有新的链接都LIST_ADD_HEAD struct mg_mgr {struct mg_connection *conns; // 每个连接都是一个struct mg_connection指向连接组成的单向链表的头部struct mg_dns dns4; // DNS for IPv4struct mg_dns dns6; // DNS for IPv6int dnstimeout; // DNS resolve timeout in millisecondsbool use_dns6; // Use DNS6 server by default, see #1532unsigned long nextid; // Next connection ID该数字逐渐增大不会减小 unsigned long timerid; // Next timer IDvoid *userdata; // Arbitrary user data pointervoid *tls_ctx; // TLS context shared by all TLS sessionsuint16_t mqtt_id; // MQTT IDs for pub/subvoid *active_dns_requests; // DNS requests in progressstruct mg_timer *timers; // Active timersint epoll_fd; // Used when MG_EPOLL_ENABLE1void *priv; // Used by the MIP stacksize_t extraconnsize; // Used by the MIP stackMG_SOCKET_TYPE pipe; // Socketpair end for mg_wakeup() #if MG_ENABLE_FREERTOS_TCPSocketSet_t ss; // NOTE(lsm): referenced from socket struct #endif };struct mg_connection 每次调用accept函数获得一个有效的fd时都新建一个该对象并将其加入单向链表中保存了连接的client的相关信息 struct mg_connection {struct mg_connection *next; // 指向下一个clientstruct mg_mgr *mgr; // Our containerstruct mg_addr loc; // host地址信息struct mg_addr rem; // client地址信息void *fd; // Connected socket, or LWIP dataunsigned long id; // Auto-incrementing unique connection ID给client的唯一id但不一定连续不知道有什么含义struct mg_iobuf recv; // Incoming datastruct mg_iobuf send; // Outgoing datastruct mg_iobuf prof; // Profile data enabled by MG_ENABLE_PROFILEstruct mg_iobuf rtls; // TLS only. Incoming encrypted datamg_event_handler_t fn; // User-specified event handler function,在main中cbvoid *fn_data; // User-specified function parametermg_event_handler_t pfn; // Protocol-specific handler function处理协议的函数如http_cbvoid *pfn_data; // Protocol-specific function parameterchar data[MG_DATA_SIZE]; // Arbitrary connection datavoid *tls; // TLS specific data// 位域下面这么多总共占4个字节unsigned is_listening : 1; // Listening connection, 是否为监听fdunsigned is_client : 1; // Outbound (client) connection mongoose作为client程序时会用到unsigned is_accepted : 1; // Accepted (server) connection 接受来自client的链接时设为1在accept_conn处// 在http server中并 监听描述符以及client描述符都是非阻塞的unsigned is_resolving : 1; // Non-blocking DNS resolution is in progressunsigned is_arplooking : 1; // Non-blocking ARP resolution is in progressunsigned is_connecting : 1; // Non-blocking connect is in progressunsigned is_tls : 1; // TLS-enabled connectionunsigned is_tls_hs : 1; // TLS handshake is in progressunsigned is_udp : 1; // UDP connectionunsigned is_websocket : 1; // WebSocket connectionunsigned is_mqtt5 : 1; // For MQTT connection, v5 indicatorunsigned is_hexdumping : 1; // Hexdump in/out trafficunsigned is_draining : 1; // Send remaining data, then close and freeunsigned is_closing : 1; // Close and free the connection immediatelyunsigned is_full : 1; // Stop reads, until clearedunsigned is_resp : 1; // Response is still being generated生在生成c-sendunsigned is_readable : 1; // Connection is ready to readunsigned is_writable : 1; // Connection is ready to write };struct mg_http_message 存储解析后的http信息 struct mg_str {const char *ptr; // Pointer to string datasize_t len; // String len };struct mg_http_header {struct mg_str name; // Header namestruct mg_str value; // Header value };struct mg_http_message {struct mg_str method, uri, query, proto; // Request/response linestruct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers MG_MAX_HTTP_HEADERS30struct mg_str body; // Bodystruct mg_str head; // Request headersstruct mg_str message; // Request headers body };二、函数 MG_LOG 默认log级别为MG_LL_INFO2 #define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args) #define MG_INFO(args) MG_LOG(MG_LL_INFO, args) #define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args) #define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)#define MG_LOG(level, args) \do { \if ((level) mg_log_level) { \mg_log_prefix((level), __FILE__, __LINE__, __func__); \mg_log args; \} \} while (0) // log的前缀 void mg_log_prefix(int level, const char *file, int line, const char *fname) {const char *p strrchr(file, /);char buf[41];size_t n;if (p NULL) p strrchr(file, \\);n mg_snprintf(buf, sizeof(buf), %-6llx %d %s:%d:%s, mg_millis(), level,p NULL ? file : p 1, line, fname);if (n sizeof(buf) - 2) n sizeof(buf) - 2;while (n sizeof(buf)) buf[n] ;logs(buf, n - 1); } // 打印内容 void mg_log(const char *fmt, ...) {va_list ap;va_start(ap, fmt);mg_vxprintf(s_log_func, s_log_func_param, fmt, ap);va_end(ap);logs(\r\n, 2); }mg_http_listen struct mg_connection *mg_http_listen(struct mg_mgr *mgr, const char *url,mg_event_handler_t fn, void *fn_data)该函数精简后类似于 if ( (fd socket(af, type, proto)) -1 ) {MG_ERROR((socket: %d, MG_SOCK_ERR(-1))); } else if ((rc setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) on, sizeof(on))) ! 0) {MG_ERROR((setsockopt(SO_REUSEADDR): %d, MG_SOCK_ERR(rc))); } else if ((rc bind(fd, usa.sa, slen)) ! 0) {MG_ERROR((bind: %d, MG_SOCK_ERR(rc))); } else if ( (rc listen(fd, 128)) ! 0 ) {MG_ERROR((listen: %d, MG_SOCK_ERR(rc))); } else {// 这里考虑到了是否有ipv6所以掉了个函数处理setlocaddr(fd, c-loc); // 将host地址写入监听描述符对应的struct mg_connection中mg_set_non_blocking_mode(fd); // 设置描述符的O_NONBLOCK以及FD_CLOEXECc-fd S2PTR(fd);MG_EPOLL_ADD(c); // 加入epollsuccess true; } 设置监听描述符对应的结构体并将其加入mgr的conns链表MG_EPOLL_X宏 水平触发模式 #define MG_EPOLL_ADD(c) \do { \struct epoll_event ev {EPOLLIN | EPOLLERR | EPOLLHUP, {c}}; \epoll_ctl(c-mgr-epoll_fd, EPOLL_CTL_ADD, (int) (size_t) c-fd, ev); \} while (0) #define MG_EPOLL_MOD(c, wr) \do { \struct epoll_event ev {EPOLLIN | EPOLLERR | EPOLLHUP, {c}}; \if (wr) ev.events | EPOLLOUT; \epoll_ctl(c-mgr-epoll_fd, EPOLL_CTL_MOD, (int) (size_t) c-fd, ev); \} while (0)mg_mgr_poll man函数最终会进入while (s_signo 0) mg_mgr_poll(mgr, 1000); 死循环中 在1000并发量时测试点 max有多大n epoll_wait有多大链表的大小是多少其中有效的有多少个无效的有多少个最大文件描述符的值是多少 void mg_mgr_poll(struct mg_mgr *mgr, int ms) {struct mg_connection *c, *tmp; // 获取epoll通知(epoll_wait)设置对应mg_connection的标志位mg_iotest(mgr, ms);// 遍历单向链表for (c mgr-conns; c ! NULL; c tmp) {tmp c-next;if (c-is_resolving || c-is_closing) {// Do nothing} else if (c-is_listening c-is_udp 0) {if (c-is_readable) accept_conn(mgr, c);} else if (c-is_connecting) { // http server中这里几乎一直处于0if (c-is_readable || c-is_writable) connect_conn(c);} else {if (c-is_readable) read_conn(c);if (c-is_writable) write_conn(c);}if (c-is_draining c-send.len 0) c-is_closing 1;if (c-is_closing) close_conn(c);} }static void mg_iotest(struct mg_mgr *mgr, int ms) {size_t max 1;for (struct mg_connection *c mgr-conns; c ! NULL; c c-next) {c-is_readable c-is_writable 0;if (c-rtls.len 0) ms 1, c-is_readable 1;if (can_write(c)) MG_EPOLL_MOD(c, 1); // 只要c-send.len 0就触发EPOLLOUTif (c-is_closing) ms 1;max;}struct epoll_event *evs (struct epoll_event *) alloca(max * sizeof(evs[0]));int n epoll_wait(mgr-epoll_fd, evs, (int) max, ms);for (int i 0; i n; i) {struct mg_connection *c (struct mg_connection *) evs[i].data.ptr;if (evs[i].events EPOLLERR) {mg_error(c, socket error); // 当c-send.len的大小和http报文的Content-Length大小不对应时会导致EPOLLERR原因未知} else if (c-is_readable 0) {bool rd evs[i].events (EPOLLIN | EPOLLHUP);bool wr evs[i].events EPOLLOUT;c-is_readable can_read(c) rd ? 1U : 0;c-is_writable can_write(c) wr ? 1U : 0;if (c-rtls.len 0) c-is_readable 1;}} }在一个mg_mgr_poll循环中受限通过mg_iotest将对应事件的标志位进行设置is_readableis_writable再通过循环即标志位处理对应事件 accept_conn函数通过accept获取client fd然后对其结构体和fd进行设置 static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {struct mg_connection *c NULL;union usa usa; socklen_t sa_len sizeof(usa);int fd accept(FD(lsn), usa-sa, sa_len);if (fd 0) {MG_ERROR((%lu accept failed, errno %d, lsn-id, MG_SOCK_ERR(-1)));} else if ((c mg_alloc_conn(mgr)) NULL) {MG_ERROR((%lu OOM, lsn-id));close(fd);} else {tomgaddr(usa, c-rem, sa_len ! sizeof(usa.sin)); // 将remote地址写入c-remLIST_ADD_HEAD(struct mg_connection, mgr-conns, c);c-fd S2PTR(fd);MG_EPOLL_ADD(c);mg_set_non_blocking_mode(FD(c)); // 设置描述符的O_NONBLOCK以及FD_CLOEXECsetsockopts(c); // setsockoptc-is_accepted 1;c-is_hexdumping lsn-is_hexdumping;c-loc lsn-loc;c-pfn lsn-pfn;c-pfn_data lsn-pfn_data;c-fn lsn-fn;c-fn_data lsn-fn_data;MG_DEBUG((%lu %ld accepted %M - %M, c-id, c-fd, mg_print_ip_port,c-rem, mg_print_ip_port, c-loc));// http server 下无事发生mg_call(c, MG_EV_OPEN, NULL);mg_call(c, MG_EV_ACCEPT, NULL);} }read_conn函数非阻塞读到c-recv.buf中然后交由iolog处理。iolog会判断n的返回值。if EINPROGRESS || EWOULDBLOCK则什么也不做elif0则设is_closing 1随后会TODO:elif n0 则调用mg_call(c, MG_EV_READ, n)它通过函数指针调用http_cb函数解析http协议。 static void http_cb(struct mg_connection *c, int ev待处理事件(该函数只处理MG_EV_READMG_EV_CLOSE), void *ev_data未使用)函数会解析c-recv.buf中的http协议(解析字符)之后f (c-is_accepted) c-is_resp 1;调用mg_call(c, MG_EV_HTTP_MSG, hm);将http解析结果交由cb函数进行处理该函数会写c-send.buf, return; 然后清除c-recvhttp_cb return。 iolog(c, buf, n, true);返回后read_conn结束。 n recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);static void read_conn(struct mg_connection *c) {if (ioalloc(c, c-recv)) {char *buf (char *) c-recv.buf[c-recv.len];size_t len c-recv.size - c-recv.len;long n -1n recv(FD(c), (char *) buf, len, MSG_NONBLOCKING); // 文件描述符是非阻塞的非阻塞接收// n 经过处理后可为 -1 -2 -3iolog(c, buf, n, true);} }write_conn函数通过send函数将c-send.buf发送然后调用iolog 对n处理。然后清理c-send然后if (c-send.len 0)MG_EPOLL_MOD(c, 0);再掉mg_call(c, MG_EV_WRITE, n);iolog return后write_conn也结束 static void write_conn(struct mg_connection *c) {long n send(FD(c), c-send.buf, c-send.len, MSG_NONBLOCKING);// 文件描述符是非阻塞的非阻塞接收// n 经过处理后可为 -1 -2 -3iolog(c, buf, n, false); }question mg_http_reply函数当继续调用mg_printf(c, fmt, …)而不修改Content-Length时 浏览器不能接收全部的数据is_closing何时被设置为1的如果client发一次server发一次不会触发is_closing1莫非是等待conn_fd断开的时候触发EPOLLHUP然后间接关闭若是如此如何触发的问题1 参考链接 https://mongoose.ws/documentation/ https://github.com/cesanta/mongoose
http://www.zqtcl.cn/news/405620/

相关文章:

  • js打开网站wordpress线报主题
  • 怎么做网站首页弹幕外贸网站高端定做
  • asp.net mvc 做网站做网站原型的软件
  • wordpress网站恢复北京app建设 网站开发公司
  • 给别人做设计的网站aso优化师工作很赚钱吗
  • 网店网站建设规划方案入门编程软件
  • 网站布局企业安全文化建设导则
  • 胶东国际机场建设有限公司网站2021重大军事新闻
  • 企业网站优化的方式萍乡市建设局网站王丽
  • 做网站的收费标准社保网上服务大厅
  • php网站开发安全网站建设管理教程视频教程
  • 网站建设的空间是什么意思海络网站
  • 深圳华强北今晚网站优化推广公司
  • 网站建设行业好做吗太原网站改版
  • 寿光企业建站流程个人网站用什么软件
  • 网站建设与管理自考本全国卷wordpress 关闭文章修订
  • 兴义市建设局网站首页网站开发项目实训总结
  • 个人网站空间收费网络软文营销案例
  • 网站开发文件结构组成微网站移交
  • 西安全网优化 西安网站推广网页浏览器缩略词
  • 网站开发及企业推广营销型网站建设怎么收费
  • 网站建设与管理ppt课件百度云盘关键词推广营销
  • c asp.net网站开发书宁波建设业协会网站
  • 政务网站建设发言材料知名互联网公司有哪些
  • 网站搭建制作建e室内设计网画图
  • 重庆市建设工程施工安全管理信息网北京seo公司网站
  • 国外做调查问卷的网站建设邮费自己的网站 要不要购买服务器的
  • 网站建设和优化排名四川建设网官网证书查询入口
  • 如何搜名字搜到自己做的网站电子商务平台icp备案证明
  • 网站建设与管理工作内容北京网站建设价