• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-161  評論-223  文章-30  trackbacks-0
             
               iocp是Windows NT操作系統(tǒng)的一種高效IO模型,對應(yīng)于Linux中的epoll和FreeBSD中的kqueue,nginx對ske(select、kqueue和epoll的首寫字母組合)的支持很好,但截止到1.6.2版本,還不支持iocp。由于ske都是反應(yīng)器模式,即先注冊IO事件,當(dāng)IO事件發(fā)生(讀寫通知)時,在其回調(diào)內(nèi)主動調(diào)用API來讀或?qū)憯?shù)據(jù);而iocp是前攝器模式,要先投遞IO操作,才能引發(fā)IO事件(完成通知)的發(fā)生,在其回調(diào)內(nèi)數(shù)據(jù)已被動由操作系統(tǒng)讀或?qū)懲瓿伞R虼耍琲ocp的特點決定了nginx對它的支持與ske有所不同。通過hg clone http://hg.nginx.org/nginx下載的nginx源代碼,雖然實現(xiàn)了iocp事件模塊、異步接受連接、部分異步讀寫,但根本不能正常工作,而且不支持異步連接和SCM服務(wù)控制,筆者在參考ske模塊的實現(xiàn)基礎(chǔ)上,改進(jìn)支持了如下特性:
                  1. 異步接受連接時的負(fù)載均衡
                  2. 正反向代理的異步連接
                  3. 異步聚合讀寫
                  4. 域名解析時的UDP異步接收
                  5. 異步文件傳輸
                  6. SCM服務(wù)控制
               由于2、4、6均為原創(chuàng),其它幾點的思路皆源于ske模塊的實現(xiàn)(只是平臺API不同),因此本文先闡述異步連接的實現(xiàn)。為了兼容select事件模塊,所有iocp相關(guān)的代碼使用NGX_HAVE_IOCP宏和(或)NGX_USE_IOCP_EVENT標(biāo)志包圍,其中NGX_HAVE_IOCP宏用于條件編譯,在WIN32平臺下,定義為1;當(dāng)選擇的事件模塊為iocp時,全局變量ngx_event_flags才包含NGX_USE_IOCP_EVENT標(biāo)志。

            異步連接對端
               由ngx_event_connect_peer函數(shù)(這里省去了與異步連接無關(guān)的代碼)實現(xiàn),定義在event/ngx_event_connect.c中,因為connect不支持異步連接事件的完成通知,所以要使用擴(kuò)展API ConnectEx。 
             1ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc)
             2{
             3    int                rc;
             4    ngx_int_t          event;
             5    ngx_err_t          err;
             6    ngx_uint_t         level,family;
             7    ngx_socket_t       s;
             8    ngx_event_t       *rev, *wev;
             9    
            10    s = ngx_socket(family = pc->sockaddr->sa_family, SOCK_STREAM, 0);
            11              
            12    #if (NGX_HAVE_IOCP)
            13    if((pc->local==NULL||pc->local->sockaddr->sa_family != family) 
            14        && (ngx_event_flags & NGX_USE_IOCP_EVENT)){
            15        if(ngx_iocp_set_localaddr(pc->log,family,&pc->local) != NGX_OK)
            16            goto failed;    
            17    }

            18    #endif
            19       
            20    
            21    #if (NGX_HAVE_IOCP)
            22    if(ngx_event_flags&NGX_USE_IOCP_EVENT){        
            23        LPWSAOVERLAPPED   ovlp;
            24        ovlp = (LPWSAOVERLAPPED)&wev->ovlp;
            25        ngx_memzero(ovlp,sizeof(WSAOVERLAPPED));
            26        wev->ovlp.type = NGX_IOCP_CONNECT;
            27        rc = ngx_connectex(s,pc->sockaddr,pc->socklen,NULL,0,NULL,ovlp) ? 0 : -1;
            28    
            29    }
            else
            30        rc = connect(s, pc->sockaddr, pc->socklen);
            31    #else
            32      rc = connect(s, pc->sockaddr, pc->socklen);
            33    #endif
            34    
            35    if (rc == -1{
            36        err = ngx_socket_errno;
            37        if (err != NGX_EINPROGRESS
            38    #if (NGX_WIN32)
            39        /* Winsock returns WSAEWOULDBLOCK (NGX_EAGAIN) */
            40        && err != NGX_EAGAIN
            41    #if (NGX_HAVE_IOCP)
            42        && err != WSA_IO_PENDING
            43    #endif
            44    #endif
            45            ){
            46            
            47            ngx_log_error(level, c->log, err, "connect() to %V failed", pc->name);
            48            ngx_close_connection(c);
            49            pc->connection = NULL;
            50          
            51            return NGX_DECLINED;
            52        }

            53    }

            54    
            55}
               調(diào)用ConnectEx前要先bind本地地址,不然發(fā)生WSAEINVAL錯誤;由于域名解析可能返回IPv6記錄,導(dǎo)致創(chuàng)建本地套接字的地址族為AF_INET6,因此bind時需要匹配IPv6地址,不然發(fā)生WSAEFAULT錯誤,導(dǎo)致nginx返回Internal Server Error錯誤給前端,因此綁定前要調(diào)用ngx_iocp_set_localaddr設(shè)定正確的本地地址,當(dāng)且僅當(dāng)pc->local為空或地址族不匹配時。

            本地初始化與設(shè)定
               支持IPv6,實現(xiàn)在event/modules/ngx_iocp_module.c。
               地址變量定義如下。
            1static struct sockaddr_in  sin;
            2#if (NGX_HAVE_INET6)
            3static struct sockaddr_in6  sin6;
            4#endif
            5static ngx_addr_t           local_addr;
               sin對應(yīng)IPv4,sin6對應(yīng)IPv6,作為bind的套接字本地地址。

               sin和sin6在啟動iocp事件模塊時調(diào)用ngx_iocp_init初始化。   
             1static ngx_int_t ngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer)
             2{
             3    
             4  sin.sin_family = AF_INET;
             5  sin.sin_port = 0;
             6  sin.sin_addr.s_addr = INADDR_ANY;
             7    
             8#if (NGX_HAVE_INET6)
             9    sin6.sin6_family = AF_INET6;
            10    sin6.sin6_port = 0;
            11    sin6.sin6_addr = in6addr_any;
            12#endif
            13    
            14  local_addr.name.len = sizeof("INADDR_ANY"- 1;
            15  local_addr.name.data = (u_char *)"INADDR_ANY";    
            16    
            17}
               不論IP地址或端口,都指定為0,表示由系統(tǒng)自動分配出口IP地址和未占用的端口。

               本地設(shè)定由ngx_iocp_set_localaddr實現(xiàn)。
             1ngx_int_t ngx_iocp_set_localaddr(ngx_log_t *log, in_port_t family, ngx_addr_t **local)
             2{
             3    struct sockaddr *sa;
             4    socklen_t len;
             5    
             6    if(AF_INET == family){            
             7        sa = &sin;
             8        len = sizeof(struct sockaddr_in);        
             9    }

            10#if (NGX_HAVE_INET6)
            11    else if(AF_INET6 == family){
            12        sa = &sin6;
            13        len = sizeof(struct sockaddr_in6);
            14    }

            15#endif
            16    else{
            17        ngx_log_error(NGX_LOG_ALERT, log, 0"not supported address family");
            18        return NGX_ERROR;        
            19    }

            20
            21    local_addr.sockaddr = sa;
            22    local_addr.socklen = len;
            23    *local = &local_addr;
            24
            25    return NGX_OK;
            26}
               對于除IPv4和IPv6外的協(xié)議族,則記錄一個錯誤日志。必要時也可擴(kuò)展支持其它的協(xié)議族,例如NetBIOS(對應(yīng)地址族為AF_NETBIOS),但要看ConnectEx是否支持。
            posted @ 2015-06-24 17:02 春秋十二月 閱讀(7657) | 評論 (1)編輯 收藏
               ICMP在IP系統(tǒng)間傳遞差錯和管理報文,是任何IP系統(tǒng)必須實現(xiàn)的組成部分。Linux 2.6.34中ICMP模塊的實現(xiàn)在linux/icmp.h,net/icmp.h和ipv4/icmp.c中,導(dǎo)出了icmp_err_convert數(shù)組和icmp_send函數(shù),供其它網(wǎng)絡(luò)子系統(tǒng)使用。在其它網(wǎng)絡(luò)子系統(tǒng)中,當(dāng)檢測到錯誤時,調(diào)用icmp_send產(chǎn)生并發(fā)送相應(yīng)的ICMP差錯消息到源主機(jī);當(dāng)源主機(jī)收到ICMP不可達(dá)差錯消息,傳遞到原始套接字和傳輸層,而它們使用icmp_err_convert把對應(yīng)的消息代碼轉(zhuǎn)換成套接字層比較容易理解的錯誤代碼。在內(nèi)核空間中可發(fā)送的ICMP消息包括查詢應(yīng)答和差錯報文,下面總結(jié)了產(chǎn)生這兩類消息的網(wǎng)絡(luò)子系統(tǒng)(及函數(shù))與錯誤轉(zhuǎn)換。


            應(yīng)答消息
               應(yīng)答消息由ICMP模塊的內(nèi)部函數(shù)icmp_reply而非icmp_send發(fā)送。根據(jù)RFC1122 3.2.2.9規(guī)范, 除非一個主機(jī)作為地址掩碼代理,否則不能發(fā)送回復(fù),這對應(yīng)ICMP的icmp_address實現(xiàn)為空,因此上表沒有列出地址掩碼應(yīng)答項(內(nèi)核符號為ICMP_ADDRESSREPLY)。

            差錯消息
               差錯消息由中間路由器或目的主機(jī)產(chǎn)生,當(dāng)數(shù)據(jù)報不能成功提交給目的主機(jī)時。從上表可見,在IP層的接收、本地處理、轉(zhuǎn)發(fā)和輸出各過程中,都可能產(chǎn)生差錯消息;在傳輸層如果對應(yīng)的端口沒有打開,那么UDP會產(chǎn)生ICMP端口不可達(dá)差錯,而TCP則會使用自己的差錯處理機(jī)制發(fā)送一個RST復(fù)位包,這也是上表沒有列出TCP子系統(tǒng)的原因。對于重定向差錯,由ICMP模塊的icmp_redirect調(diào)用ip_rt_redirect更新路由;其它差錯則由icmp_unreach處理。


            錯誤轉(zhuǎn)換
               第2列為icmp_err_convert數(shù)組索引,第4列也就是調(diào)用socket API出錯時返回的errno,最后1列為icmp_err_convert中的fatal成員取值,0表示非致命錯誤,1表示致命錯誤,需要報告給用戶進(jìn)程。錯誤轉(zhuǎn)換會被RAW的raw_err、TCP的tcp_v4_err和UDP的udp_err用到,對于ICMP_DEST_UNREACH類型的差錯,使用上表轉(zhuǎn)換;ICMP_SOURCE_QUENCH類型的忽略不處理;ICMP_PARAMETERPROB類型的轉(zhuǎn)換成EPROTO(協(xié)議錯誤);ICMP_TIME_EXCEEDED類型的轉(zhuǎn)換成EHOSTUNREACH
               在這要注意,從ICMP_PORT_UNREACH到ECONNREFUSED的轉(zhuǎn)換,不適用于TCP,原因已在上節(jié)說明;而對于UDP的未連接套接字,如果主機(jī)在線而端口沒打開,調(diào)用sendto得不到ECONNREFUSED錯誤,但recvfrom會阻塞,這是因為雖然內(nèi)核收到了ICMP差錯,但沒上報給應(yīng)用進(jìn)程。盡管如此,如果想得到ECONNREFUSED錯誤,那么可以寫個ICMP守護(hù)進(jìn)程,應(yīng)用進(jìn)程先把它的套接字描述符通過unix域套接口傳遞到ICMP守護(hù)進(jìn)程,而守護(hù)進(jìn)程使用raw socket來接收ICMP差錯,再發(fā)給應(yīng)用進(jìn)程。


            發(fā)送限速
               不論一般差錯消息還是重定向差錯消息,發(fā)送限速針對的都是特定目標(biāo)主機(jī)。
               一般限速
               在使用icmp_send發(fā)送差錯消息(PMTU消息除外)時,為減少網(wǎng)絡(luò)擁塞而限制了發(fā)送的速率,限速由xrlim_allow函數(shù)實現(xiàn),定義在ipv4/icmp.c中。
             1#define XRLIM_BURST_FACTOR 6
             2int xrlim_allow(struct dst_entry *dst, int timeout)
             3{
             4    unsigned long now, token = dst->rate_tokens;
             5    int rc = 0;
             6
             7    now = jiffies;
             8    token += now - dst->rate_last;
             9    dst->rate_last = now;
            10    if (token > XRLIM_BURST_FACTOR * timeout)
            11        token = XRLIM_BURST_FACTOR * timeout;
            12    if (token >= timeout) {
            13        token -= timeout;
            14        rc = 1;
            15    }

            16    dst->rate_tokens = token;
            17    return rc;
            18}
               dst為目標(biāo)路由緩存,timeout為允許發(fā)送的超時(單位為jiffies),dst->rate_tokens記錄令牌的個數(shù),當(dāng)令牌個數(shù)不小于timeout時,則減少timeout并允許發(fā)送一個消息;反之則不能發(fā)送,需等到令牌個數(shù)累積到大于timeout時才能發(fā)送,但是不能無限大,否則就會導(dǎo)致在一個可能很短的timeout內(nèi),發(fā)送遠(yuǎn)多于6個的消息,引起ICMP風(fēng)暴,所以這里限制了令牌的最大值為XRLIM_BURST_FACTOR*timeout即6倍的超時,也就是說在一個timeout內(nèi),最多能發(fā)送6個差錯消息。 
              
               重定向限速
               路由子系統(tǒng)使用ip_rt_send_redirect來發(fā)送重定向消息,定義在ipv4/route.c中,該函數(shù)內(nèi)部調(diào)用icmp_send實現(xiàn),在它的限速基礎(chǔ)上,使用指數(shù)回退算法控制發(fā)送速率。
             1void ip_rt_send_redirect(struct sk_buff *skb)
             2{
             3    struct rtable *rt = skb_rtable(skb);
             4    
               
             5
             6    /* No redirected packets during ip_rt_redirect_silence;
             7     * reset the algorithm.
             8     */

             9    if (time_after(jiffies, rt->u.dst.rate_last + ip_rt_redirect_silence))
            10        rt->u.dst.rate_tokens = 0;
            11
            12    /* Too many ignored redirects; do not send anything
            13     * set u.dst.rate_last to the last seen redirected packet.
            14     */

            15    if (rt->u.dst.rate_tokens >= ip_rt_redirect_number{
            16        rt->u.dst.rate_last = jiffies;
            17        return;
            18    }

            19
            20    /* Check for load limit; set rate_last to the latest sent
            21     * redirect.
            22     */

            23    if (rt->u.dst.rate_tokens == 0 || time_after(jiffies, (rt->u.dst.rate_last (ip_rt_redirect_load << rt->u.dst.rate_tokens)))) {
            24        icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway);
            25        rt->u.dst.rate_last = jiffies;
            26        ++rt->u.dst.rate_tokens;
            27        
            28    }

            29}
               重定向差錯使用ip_rt_redirect_silence(默認(rèn)為(HZ/50)<<10)、ip_rt_redirect_number(默認(rèn)為9)和ip_rt_redirect_load(默認(rèn)為HZ/50)3個量來控制發(fā)送的速率;rt->u.dst.rate_last記錄上次發(fā)送的時間,rt->u.dst.rate_tokens累計發(fā)送總數(shù),最大值為ip_rt_redirect_number;當(dāng)兩次發(fā)送的時間間隔超過ip_rt_redirect_silence或ip_rt_redirect_load<<rt->u.dst.rate_tokens,并且發(fā)送總數(shù)不超過ip_rt_redirect_number時,才允許發(fā)送一個,這樣一來,在ip_rt_redirect_silence間隔內(nèi),每次發(fā)送的超時呈2的指數(shù)增長,達(dá)到了變減速發(fā)送的效果,直到總數(shù)達(dá)到ip_rt_redirect_number時停止發(fā)送,這是因為源主機(jī)可能忽略了重定向消息所以停止發(fā)送;當(dāng)ip_rt_redirect_silence時間過后,又允許發(fā)送了,這是因為認(rèn)為源主機(jī)沒有更新路由所以又需要發(fā)送。
            posted @ 2015-05-18 19:52 春秋十二月 閱讀(2804) | 評論 (0)編輯 收藏
                 摘要:    接上篇初始化與創(chuàng)建,本篇闡述Socket操作和銷毀兩部分的實現(xiàn)。 Socket操作    系統(tǒng)調(diào)用read(v)、write(v)是用戶空間讀寫socket的一種方法,為了弄清楚它們是怎么通過VFS將請求轉(zhuǎn)發(fā)到特定協(xié)議的實現(xiàn),下面以read為例(write同理),并假定文件描述符對應(yīng)的是IPv4 TCP類型的socket...  閱讀全文
            posted @ 2015-05-03 16:55 春秋十二月 閱讀(5282) | 評論 (0)編輯 收藏
                 摘要: 引言    在Unix的世界里,萬物皆文件,通過虛擬文件系統(tǒng)VFS,程序可以用標(biāo)準(zhǔn)的Unix系統(tǒng)調(diào)用對不同的文件系統(tǒng),甚至不同介質(zhì)上的文件系統(tǒng)進(jìn)行讀寫操作。對于網(wǎng)絡(luò)套接字socket也是如此,除了專屬的Berkeley Sockets API,還支持一些標(biāo)準(zhǔn)的文件IO系統(tǒng)調(diào)用如read(v)、write(v)和close等。那么為什么socket也支持文件IO系統(tǒng)調(diào)...  閱讀全文
            posted @ 2015-05-03 16:31 春秋十二月 閱讀(8668) | 評論 (0)編輯 收藏
                 摘要: 字符集合     依據(jù)RFC3986 2規(guī)范,HTTP URI中允許出現(xiàn)的US-ASCII字符的子集,可以分成保留、未保留及轉(zhuǎn)義這幾類,每類的全部字符列表如下       ● 保留:  : / ? # [ ] @ ! $ & '( ) * + ,; =共18個,一般...  閱讀全文
            posted @ 2015-02-10 18:40 春秋十二月 閱讀(4747) | 評論 (1)編輯 收藏
                 摘要: 腳本概述   nginx是一款著名的開源web服務(wù)器,為方便升級與恢復(fù),編寫了一個簡單的腳本,因為升級備份了可執(zhí)行文件和配置文件(后綴名為old),所以可用于恢復(fù)。當(dāng)升級時,若nginx正在運行,則不中斷服務(wù)進(jìn)行平滑升級,否則直接拷貝覆蓋;當(dāng)恢復(fù)時,若nginx正在運行,則不中斷服務(wù)進(jìn)行平滑恢復(fù),否則直接拷貝覆蓋。是否正在運行根據(jù)pid來判斷,而pid從pid文件讀取...  閱讀全文
            posted @ 2015-01-19 00:36 春秋十二月 閱讀(2056) | 評論 (0)編輯 收藏
                 摘要:    本文描述了一種簡單的跨平臺鎖框架的設(shè)計與實現(xiàn),該框架小巧實用、易于擴(kuò)展,它的特點如下:      ● 實現(xiàn)了線程間互斥鎖      ● 實現(xiàn)優(yōu)化了單線程環(huán)境中的空鎖和空級別鎖      ● 支持編譯時或運行時選擇鎖   ...  閱讀全文
            posted @ 2014-12-28 23:38 春秋十二月 閱讀(2456) | 評論 (6)編輯 收藏
               眾所周知,TLS是指線程局部存儲,F(xiàn)IFO是Unix中的命名管道,可用于無關(guān)進(jìn)程間的通信,而本文描述的TLS FIFO是指這樣一種機(jī)制:如果一個線程在每次IO操作時,若沒有連接,則先連接到FIFO服務(wù)端,再將連接關(guān)聯(lián)到這個線程的TLS中,這里的連接即創(chuàng)建并打開唯一的FIFO,之后的讀寫就在這個FIFO連接上進(jìn)行;當(dāng)FIFO連接斷開時,在下次IO操作時會自動重連。這樣一來,用戶程序就只要調(diào)用相關(guān)的IO操作,而不必管理連接,極大地簡化了程序。使用FIFO通信前先要創(chuàng)建FIFO再打開它,其中創(chuàng)建是最重要的操作,結(jié)果有3種情況:成功、失敗和已存在。

            結(jié)構(gòu)定義
            typedef struct 
            {
                int fd;
                char *name;
            }ipc_fifo_t;
              fd存儲FIFO文件描述符,name存儲FIFO文件系統(tǒng)路徑名。

            接口函數(shù)
               創(chuàng)建FIFO
            ipc_fifo_t* ipc_fifo_make(const char *path,mode_t mode);
              path指定FIFO路徑,可以是絕對路徑或相對路徑,mode指定訪問權(quán)限,若成功則返回一個FIFO結(jié)構(gòu),否則為NULL;通常被ipc_fifo_open調(diào)用。
               
               打開FIFO
            int ipc_fifo_open(ipc_fifo_t **f,const char *path,int flag,mode_t mode);
              flag指定打開標(biāo)志,如果包含了O_CREAT標(biāo)志,那么調(diào)用ipc_fifo_make創(chuàng)建新的FIFO對象并在打開成功后替換*f,否則如果*f為空,就分配并初始化一個fifo結(jié)構(gòu);mode指定訪問權(quán)限,僅當(dāng)創(chuàng)建時生效。雖然f為輸入輸出參數(shù),但操作失敗時不會影響它,也就是說沒有副作用。

              ● 發(fā)送數(shù)據(jù)   
            ssize_t ipc_fifo_write(ipc_fifo_t *f,const void *data,size_t size);
              如果成功則返回已發(fā)送的字節(jié)數(shù),否則返回-1,errno表示出錯代碼。
               
              ● 接收數(shù)據(jù)
            ssize_t ipc_fifo_read(ipc_fifo_t *f,void *data,size_t size);
              如果成功則返回已發(fā)送的字節(jié)數(shù),否則返回-1,errno表示出錯代碼。

              ● 關(guān)閉FIFO
            void ipc_fifo_close(ipc_fifo_t *f);
              當(dāng)通信結(jié)束的時候,應(yīng)該調(diào)用此函數(shù)來關(guān)閉FIFO,它會先刪除FIFO文件和關(guān)閉文件描述符,最后釋放fifo結(jié)構(gòu)。

              ● 獲取TLS FIFO
            ipc_fifo_t* ipc_fifo_tls_get();
              該函數(shù)一般被發(fā)送數(shù)據(jù)接口調(diào)用,若成功則返回一個FIFO結(jié)構(gòu),否則為NULL;每個線程對應(yīng)一個FIFO對象,對于同一線程,獲取的是同一個FIFO對象,而后便可調(diào)用ipc_fifo_write來發(fā)送數(shù)據(jù)。

            工作流程
              創(chuàng)建FIFO
              適用于FIFO客戶端和服務(wù)端,但服務(wù)端由于要異步處理眾多FIFO客戶端,因此要注意以下2個問題,這也是使用FIFO技術(shù)通信的一些細(xì)節(jié)。
              1)必須以非阻塞讀寫方式打開知名FIFO,即以O(shè)_CREAT|O_RDWR|O_NONBLOCK標(biāo)志來調(diào)用ipc_fifo_open,這樣才不會阻塞等待某個客戶端以同步寫方式打開知名FIFO而返回,因為它使用O_RDWR標(biāo)志,這樣自己既讀又寫,加上O_NONBLOCK,就立即返回了。
              2)必須以非阻塞只讀方式打開對應(yīng)客戶端FIFO,即以O(shè)_RDONLY|O_NONBLOCK標(biāo)志調(diào)用ipc_fifo_open,這樣就不會阻塞接受客戶端建立連接而返回。

              建立FIFO連接
              適用于FIFO客戶端,被發(fā)送數(shù)據(jù)接口調(diào)用,考慮到服務(wù)端可能事先沒有打開知名FIFO來監(jiān)聽連接,所以這里先以異步方式寫打開知名FIFO如果成功則改以阻塞方式發(fā)送唯一路徑名到服務(wù)端,如果發(fā)送完全后,接著以同步方式寫打開唯一FIFO,這是為了等待服務(wù)端打開了對應(yīng)的唯一FIFO。

              發(fā)送數(shù)據(jù)

              適用于FIFO客戶端,當(dāng)TLS中沒有關(guān)聯(lián)對應(yīng)的FIFO時,則先調(diào)用fifo_tls_get進(jìn)入建立FIFO連接流程,而后再發(fā)數(shù)據(jù)。
            posted @ 2014-12-01 00:13 春秋十二月 閱讀(1359) | 評論 (2)編輯 收藏
                 摘要:    Web服務(wù)器為了支持https訪問,通常會使用第三方庫openssl實現(xiàn),而且為了高性能采用異步事件驅(qū)動模型,因此連接套接字被設(shè)為非阻塞類型,本文在nginx ssl模塊的基礎(chǔ)上,簡化提取它的核心框架,使用面向?qū)ο蟮姆绞矫枋觯瑥奈帐帧⒆x寫和關(guān)閉3個方面進(jìn)行了分析,由于這3個操作都是異步的,因此操作失敗后要調(diào)用SSL_get_error來獲取錯誤碼,有如下4種情況。 &n...  閱讀全文
            posted @ 2014-04-11 17:26 春秋十二月 閱讀(14001) | 評論 (0)編輯 收藏
            模板
                1. 空基類優(yōu)化
                2. 元編程技術(shù)
                    2.1. 選擇API
                    2.2. 計算最值
                    2.3. 類型選擇
                3. 封裝GCC原子操作
                4. 定制類對象的內(nèi)存管理

            算法
                1. 排序
                    1.1. 改進(jìn)的快速排序
                    1.2. 原位統(tǒng)計排序     
                2. 多叉樹
                    2.1. 深度優(yōu)先存儲
                    2.2. 迭代器的設(shè)計
                    2.3. 前序遍歷
                    2.4. 后序遍歷
                    2.5. 兄弟遍歷
                    2.6. 葉子遍歷
                    2.7. 深度遍歷 
                3. 優(yōu)先級隊列
                    3.1. 原理
                    3.2. 內(nèi)幕
                    3.3. 外觀
                4. RSA加解密的證明
                5. DSA數(shù)字簽名的推導(dǎo)
                6. 基于中國剩余定理優(yōu)化RSA解密推論的證明
                7. 總結(jié)AES加密涉及的數(shù)學(xué)定理
                8. 為什么素檢測存在概率多項式時間算法
                9. Blum數(shù)的基本定理及應(yīng)用
                10. 論證有限域上平方根的求解

            GUI 
                1. MFC中的WM_COMMAND傳遞
                2. ATL和WTL中的消息反射
                3. 工作線程與消息循環(huán)
                4. 多窗口的組合與分離
                    4.1. 接口
                    4.2. 實現(xiàn)

            跨平臺
                1. 用戶態(tài)自旋鎖
                2. 互斥鎖
                3. 信號量
                4. socket管道
                5. 鎖框架的設(shè)計與實現(xiàn)

            網(wǎng)絡(luò)
                1. 運用狀態(tài)機(jī)異步接收變長包
                2. 基于OpenSSL實現(xiàn)的安全連接
                3. TCP/IP FAQ
                    3.1. 鏈路層、網(wǎng)絡(luò)層和傳輸層
                    3.2. 插口層和應(yīng)用層
                4. Linux套接字與虛擬文件系統(tǒng)
                    4.1. 初始化和創(chuàng)建
                    4.2. 操作和銷毀
                5. Linux ICMP消息的產(chǎn)生與轉(zhuǎn)換
                6. nginx iocp
                    6.1. tcp異步連接
                    6.2. udp異步接收
                    6.3. scm服務(wù)控制
                7. TCP分組丟失時的狀態(tài)變遷
                8. 基于ENet實現(xiàn)可靠UDP通信的同步模型

            Shell應(yīng)用
                1. 自動生成并安裝服務(wù)腳本
                2. nginx升級與恢復(fù)
                3. 使用awk定位反匯編輸出
                4. 自動化批量編譯
            posted @ 2014-04-10 16:04 春秋十二月 閱讀(1861) | 評論 (0)編輯 收藏
            僅列出標(biāo)題
            共17頁: First 6 7 8 9 10 11 12 13 14 Last 
            久久99国产精品久久久| 久久精品aⅴ无码中文字字幕不卡 久久精品成人欧美大片 | 国产精品久久久久9999高清| 97久久精品人人做人人爽| 开心久久婷婷综合中文字幕| 人妻精品久久久久中文字幕一冢本| 久久亚洲私人国产精品vA| 久久久久亚洲AV成人网人人网站| 伊人热热久久原色播放www| 精品久久久久久综合日本| 亚洲欧美成人久久综合中文网| 亚洲中文久久精品无码| 国产精品18久久久久久vr| 久久国产综合精品五月天| 韩国免费A级毛片久久| 老司机午夜网站国内精品久久久久久久久 | 777久久精品一区二区三区无码| 久久久精品视频免费观看 | 999久久久免费精品国产| 成人免费网站久久久| 久久婷婷五月综合色高清| 久久婷婷午色综合夜啪| 久久精品国产一区二区电影| 精品熟女少妇av免费久久| 亚洲中文字幕久久精品无码APP| 久久久久久青草大香综合精品 | 午夜视频久久久久一区| 久久噜噜电影你懂的| 韩国免费A级毛片久久| 久久精品人人槡人妻人人玩AV | 国产精品免费看久久久香蕉| 国产∨亚洲V天堂无码久久久| 久久人人爽人人爽人人片AV不| 亚洲精品国产综合久久一线| 久久久久国产精品三级网| 久久精品亚洲福利| 开心久久婷婷综合中文字幕| 伊人久久成人成综合网222| 2021国产精品久久精品| 久久人人爽人人爽人人爽| 亚洲精品乱码久久久久久中文字幕|