Thttpd源程序解析14 连接过程详解

2024-03-14 16:59

本文主要是介绍Thttpd源程序解析14 连接过程详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

经过前面讲述Thttpd源程序每个函数的大致的功能,现在针对Thttpd如何共做接收用户的连接请求的详细过程。

当服务器正常运行的时候将会不断的根据用户设置的服务器的IP地址类型调用handle_newconnect函数进行对有连接请求的处理。handle_newconnect函数是处理用户的连接请求的主要函数。

handle_newconnect函数

handle_newconnect函数是一个死循环的函数:

(1)判断当前的连接数量是否超过了设置的最大的连接数量,如果是调用tmr_run函数执行时间hash表中超时的处理函数然后返回0;如果不是继续执行

(2)判断下一个可以使用的文件描述符是否可以使用,对于不可以使用的异常退出程序,对于可以使用的继续执行后面的过程

(3)获取下一个可以使用的连接对象的地址。

(4)判断下一个连接对象的连接地址是否分配过,对于分配过的直接执行后面的程序,对于没有分配过的进行内存分配,如果分配失败直接异常退出程序对于分配成功的继续执行后面的过程。

(5)调用httpd_get_conn函数根据返回结果进行处理:返回值为GC_FAIL(0)调用tmr_run函数执行时间hash表中超时的处理函数然后返回0,返回值为GC_NO_MORE(2)返回1,其他继续执行后面的程序。

(6)初始化连接对象的参数,更新下一个可以使用的对象在数组中的地址以及当前连接数。

(7)设置此文件描述符为非阻塞模式

(8)将此文件描述符添加至检测的文件描述符数组中。

static int handle_newconnect( struct timeval* tvP, int listen_fd )
{connecttab* c;ClientData client_data;/* This loops until the accept() fails, trying to start new** connections as fast as possible so we don't overrun the** listen queue.*/for (;;){/* Is there room in the connection table? */if ( num_connects >= max_connects ){/* Out of connection slots.  Run the timers, then the** existing connections, and maybe we'll free up a slot** by the time we get back here.*/syslog( LOG_WARNING, "too many connections!" );tmr_run( tvP );return 0;}/* Get the first free connection entry off the free list. */if ( first_free_connect == -1 || connects[first_free_connect].conn_state != CNST_FREE ){syslog( LOG_CRIT, "the connects free list is messed up" );exit( 1 );}c = &connects[first_free_connect];/* Make the httpd_conn if necessary. */if ( c->hc == (httpd_conn*) 0 ){c->hc = NEW( httpd_conn, 1 );if ( c->hc == (httpd_conn*) 0 ){syslog( LOG_CRIT, "out of memory allocating an httpd_conn" );exit( 1 );}c->hc->initialized = 0;++httpd_conn_count;}/* Get the connection. */switch ( httpd_get_conn( hs, listen_fd, c->hc ) ){/* Some error happened.  Run the timers, then the** existing connections.  Maybe the error will clear.*/case GC_FAIL:tmr_run( tvP );return 0;/* No more connections to accept for now. */case GC_NO_MORE:return 1;}c->conn_state = CNST_READING;/* Pop it off the free list. */first_free_connect = c->next_free_connect;c->next_free_connect = -1;++num_connects;client_data.p = c;c->active_at = tvP->tv_sec;c->wakeup_timer = (Timer*) 0;c->linger_timer = (Timer*) 0;c->next_byte_index = 0;c->numtnums = 0;/* Set the connection file descriptor to no-delay mode. */httpd_set_ndelay( c->hc->conn_fd );fdwatch_add_fd( c->hc->conn_fd, c, FDW_READ );++stats_connections;if ( num_connects > stats_simultaneous ){stats_simultaneous = num_connects;}}
}

httpd_get_conn函数

httpd_get_conn 函数是真正接受请求的处理函数,并未相关的请求对象重新分配内存空间,初始化连接参数

(1)判断请求是否初始化过,对于没有初始化过的重新为请求的对象的相关参数分配内存空间。

(2)调用accept函数接受用户请求。

(3)根据接受请求的返回值判断接受请求是否成功,如果失败返回GC_FAIL(0),如果成功继续执行后面的程序。

(4)判断客户端的IP地址类型是否有效,如果无效返回GC_FAIL(0),如果成功继续执行后面的程序。

(5)初始化相关的连接对象参数。

int httpd_get_conn( httpd_server* hs, int listen_fd, httpd_conn* hc )
{httpd_sockaddr sa;socklen_t sz;if ( ! hc->initialized ){hc->read_size = 0;httpd_realloc_str( &hc->read_buf, &hc->read_size, 500 );hc->maxdecodedurl =hc->maxorigfilename = hc->maxexpnfilename = hc->maxencodings =hc->maxpathinfo = hc->maxquery = hc->maxaccept =hc->maxaccepte = hc->maxreqhost = hc->maxhostdir =hc->maxremoteuser = hc->maxresponse = 0;
#ifdef TILDE_MAP_2hc->maxaltdir = 0;
#endif /* TILDE_MAP_2 */httpd_realloc_str( &hc->decodedurl, &hc->maxdecodedurl, 1 );httpd_realloc_str( &hc->origfilename, &hc->maxorigfilename, 1 );httpd_realloc_str( &hc->expnfilename, &hc->maxexpnfilename, 0 );httpd_realloc_str( &hc->encodings, &hc->maxencodings, 0 );httpd_realloc_str( &hc->pathinfo, &hc->maxpathinfo, 0 );httpd_realloc_str( &hc->query, &hc->maxquery, 0 );httpd_realloc_str( &hc->accept, &hc->maxaccept, 0 );httpd_realloc_str( &hc->accepte, &hc->maxaccepte, 0 );httpd_realloc_str( &hc->reqhost, &hc->maxreqhost, 0 );httpd_realloc_str( &hc->hostdir, &hc->maxhostdir, 0 );httpd_realloc_str( &hc->remoteuser, &hc->maxremoteuser, 0 );httpd_realloc_str( &hc->response, &hc->maxresponse, 0 );
#ifdef TILDE_MAP_2httpd_realloc_str( &hc->altdir, &hc->maxaltdir, 0 );
#endif /* TILDE_MAP_2 */hc->initialized = 1;}/* Accept the new connection. */sz = sizeof(sa);hc->conn_fd = accept( listen_fd, &sa.sa, &sz );if ( hc->conn_fd < 0 ){if ( errno == EWOULDBLOCK ){return GC_NO_MORE;}/* ECONNABORTED means the connection was closed by the client while** it was waiting in the listen queue.  It's not worth logging.*/if ( errno != ECONNABORTED ){syslog( LOG_ERR, "accept - %m" );}return GC_FAIL;}if ( ! sockaddr_check( &sa ) ){syslog( LOG_ERR, "unknown sockaddr family" );close( hc->conn_fd );hc->conn_fd = -1;return GC_FAIL;}(void) fcntl( hc->conn_fd, F_SETFD, 1 );hc->hs = hs;(void) memset( &hc->client_addr, 0, sizeof(hc->client_addr) );(void) memmove( &hc->client_addr, &sa, sockaddr_len( &sa ) );hc->read_idx = 0;hc->checked_idx = 0;hc->checked_state = CHST_FIRSTWORD;hc->method = METHOD_UNKNOWN;hc->status = 0;hc->bytes_to_send = 0;hc->bytes_sent = 0;hc->encodedurl = "";hc->decodedurl[0] = '\0';hc->protocol = "UNKNOWN";hc->origfilename[0] = '\0';hc->expnfilename[0] = '\0';hc->encodings[0] = '\0';hc->pathinfo[0] = '\0';hc->query[0] = '\0';hc->referrer = "";hc->useragent = "";hc->accept[0] = '\0';hc->accepte[0] = '\0';hc->acceptl = "";hc->cookie = "";hc->contenttype = "";hc->reqhost[0] = '\0';hc->hdrhost = "";hc->hostdir[0] = '\0';hc->authorization = "";hc->remoteuser[0] = '\0';hc->response[0] = '\0';
#ifdef TILDE_MAP_2hc->altdir[0] = '\0';
#endif /* TILDE_MAP_2 */hc->responselen = 0;hc->if_modified_since = (time_t) -1;hc->range_if = (time_t) -1;hc->contentlength = -1;hc->type = "";hc->hostname = (char*) 0;hc->mime_flag = 1;hc->one_one = 0;hc->got_range = 0;hc->tildemapped = 0;hc->first_byte_index = 0;hc->last_byte_index = -1;hc->keep_alive = 0;hc->should_linger = 0;hc->file_address = (char*) 0;return GC_OK;
}

 

 

这篇关于Thttpd源程序解析14 连接过程详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/809080

相关文章

解析 XML 和 INI

XML 1.TinyXML库 TinyXML是一个C++的XML解析库  使用介绍: https://www.cnblogs.com/mythou/archive/2011/11/27/2265169.html    使用的时候,只要把 tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.

C/C++的编译和链接过程

目录 从源文件生成可执行文件(书中第2章) 1.Preprocessing预处理——预处理器cpp 2.Compilation编译——编译器cll ps:vs中优化选项设置 3.Assembly汇编——汇编器as ps:vs中汇编输出文件设置 4.Linking链接——链接器ld 符号 模块,库 链接过程——链接器 链接过程 1.简单链接的例子 2.链接过程 3.地址和

【Altium】查找PCB上未连接的网络

【更多软件使用问题请点击亿道电子官方网站】 1、文档目标: PCB设计后期检查中找出没有连接的网络 应用场景:PCB设计后期,需要检查是否所有网络都已连接布线。虽然未连接的网络会有飞线显示,但是由于布线后期整板布线密度较高,虚连,断连的网络用肉眼难以轻易发现。用DRC检查也可以找出未连接的网络,如果PCB中DRC问题较多,查找起来就不是很方便。使用PCB Filter面板来达成目的相比DRC

Java面试题:通过实例说明内连接、左外连接和右外连接的区别

在 SQL 中,连接(JOIN)用于在多个表之间组合行。最常用的连接类型是内连接(INNER JOIN)、左外连接(LEFT OUTER JOIN)和右外连接(RIGHT OUTER JOIN)。它们的主要区别在于它们如何处理表之间的匹配和不匹配行。下面是每种连接的详细说明和示例。 表示例 假设有两个表:Customers 和 Orders。 Customers CustomerIDCus

十四、观察者模式与访问者模式详解

21.观察者模式 21.1.课程目标 1、 掌握观察者模式和访问者模式的应用场景。 2、 掌握观察者模式在具体业务场景中的应用。 3、 了解访问者模式的双分派。 4、 观察者模式和访问者模式的优、缺点。 21.2.内容定位 1、 有 Swing开发经验的人群更容易理解观察者模式。 2、 访问者模式被称为最复杂的设计模式。 21.3.观察者模式 观 察 者 模 式 ( Obser

【操作系统】信号Signal超详解|捕捉函数

🔥博客主页: 我要成为C++领域大神🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 如何触发信号 信号是Linux下的经典技术,一般操作系统利用信号杀死违规进程,典型进程干预手段,信号除了杀死进程外也可以挂起进程 kill -l 查看系统支持的信号

Jitter Injection详解

一、定义与作用 Jitter Injection,即抖动注入,是一种在通信系统中人为地添加抖动的技术。该技术通过在发送端对数据包进行延迟和抖动调整,以实现对整个通信系统的时延和抖动的控制。其主要作用包括: 改善传输质量:通过调整数据包的时延和抖动,可以有效地降低误码率,提高数据传输的可靠性。均衡网络负载:通过对不同的数据流进行不同程度的抖动注入,可以实现网络资源的合理分配,提高整体传输效率。增

Steam邮件推送内容有哪些?配置教程详解!

Steam邮件推送功能是否安全?如何个性化邮件推送内容? Steam作为全球最大的数字游戏分发平台之一,不仅提供了海量的游戏资源,还通过邮件推送为用户提供最新的游戏信息、促销活动和个性化推荐。AokSend将详细介绍Steam邮件推送的主要内容。 Steam邮件推送:促销优惠 每当平台举办大型促销活动,如夏季促销、冬季促销、黑色星期五等,用户都会收到邮件通知。这些邮件详细列出了打折游戏、

探索Elastic Search:强大的开源搜索引擎,详解及使用

🎬 鸽芷咕:个人主页  🔥 个人专栏: 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 引入 全文搜索属于最常见的需求,开源的 Elasticsearch (以下简称 Elastic)是目前全文搜索引擎的首选,相信大家多多少少的都听说过它。它可以快速地储存、搜索和分析海量数据。就连维基百科、Stack Overflow、

tf.split()函数解析

API原型(TensorFlow 1.8.0): tf.split(     value,     num_or_size_splits,     axis=0,     num=None,     name='split' ) 这个函数是用来切割张量的。输入切割的张量和参数,返回切割的结果。  value传入的就是需要切割的张量。  这个函数有两种切割的方式: 以三个维度的张量为例,比如说一