接口超时后程序还会继续执行嘛_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;}}}
17fd271c4543dbb53d72b33f9b42f164.png

handle_newconnect函数流程图

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_2 hc->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;}
f56a6523511f961157de2bd238c6c609.png

httpd_get_conn函数流程图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值