軟件開發報告_第1頁
軟件開發報告_第2頁
軟件開發報告_第3頁
軟件開發報告_第4頁
軟件開發報告_第5頁
免費預覽已結束,剩余27頁可下載查看

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、負載均衡器軟件開發報告院系:班級:成員:目錄1,可行性分析報告11.1 項目背景11.2 產品分析11.3 結論意見22 .項目開發計劃22.1 總體功能要求22.2 軟件開發平臺要求22.3 軟件項目的開發實力過程管理要求23 .軟件開發23.1 軟件的需求分析33.3 軟件的詳細設計43.4 軟件的編碼53.5 軟件的測試313.5.1 測試計劃313.5.2 軟件測試314 .項目開發總結報告321 .可行性分析報告1.1 項目背景面對龐大的數據流量,面對集中性的訪問,是不是覺得網絡服務器岌岌可危呢?不用怕,負載均衡器就能幫你緩解這個問題。負載均衡器通過虛擬IP地址方法,解決了輪流排程所

2、面臨的許多問題。使用了負載均衡器集群系統,在外部看來,像是具有一個IP地址的單一服務器一樣,當然,這個IP地址是虛擬的,它映射了集群中的每一臺機器的地址。所以,在某種程度上,負載均衡器是將整個集群的IP地址報漏給外部網絡。當請求到達負載均衡器時,它會重寫該請求的頭文件,并將之指定到集群中的機器上。如果某臺機器被從集群中移除了,請求不會別發往已經不存在的服務器上,因為所有的機器表面上都具有同一個IP地址,即使集群中的某個節點被移除了,該地址也不會發生變化。而且,internet上緩存的DN舔目也不再是問題了。當返回一個應答時,客戶端看到的只是從負載均衡器上所返回的結果。也就是說,客戶端操作的對象

3、是負載均衡器,對于其更后端的操作,對客戶端來講,是完全透明的。1.2 產品分析服務器一致性負載均衡器讀取客戶端發出的每一個請求中所包含的cookies或url解釋。基于所讀出的這些信息,負載均衡器就可以重寫報頭并將請求發往集群中合適的節點上,該節點維護著相應客戶端請求的會話信息。在HTTP®信中,負載均衡器可以提供服務器一致性,但并不是通過一個安全的途徑(例如:HTTPS來提供這種服務。當消息被加密后(SSD,負載均衡器就不能讀出隱藏在其中的會話信息。通過故障恢復機制獲得高可靠性故障恢復發生在當集群中某個節點不能處理請求,需將請求重新導向到其他節點時。主要有兩種故障恢復:請求級故障恢

4、復。當集群中的一個節點不能處理請求時(通常是由于down機),請求被發送到其他節點。當然,在導向到其他節點的同時,保存在原節點上的會話信息將會丟失。透明會話故障恢復。當一個引用失敗后,負載均衡器會將之發送到集群中其他的節點上,以完成操作,這一點對用戶來說是透明的。由于透明會話故障恢復需要節點具備相應的操作信息,因此為了實現該功能,集群中的所有節點必須具有公共存儲區域或通用數據庫,存儲會話信息數據,以提供每個節點在進行單獨進程會話故障恢復時所需要的操作信息。既然所有的Wetg用請求都必須經過負載均衡系統,那么系統就可以確定活動會話的數量,在任何實例訪問中的活動會話的數目,應答的次數,高峰負載次數

5、,以及在高峰期和低谷期的會話的數目,還有其他更多的。所有的這些統計信息都可以被很好的用來調整整個系統的性能。1.3 結論意見雖然此項目存在一定的技術難度和風險,但我們對項目要達到的目標十分清楚,對所要開發系統將要實現的功能也非常了解。而且有一些成品作為參考,并且在項目的實施過程中我們能夠獲得幫助,我認為只要我們能夠認真思考、仔細規劃、明確分工,我們可以承擔此項目的開發。2 .項目開發計劃2.1 總體功能要求1 .擴展網絡設備和服務器的帶寬2 .增加吞吐量3 .加強網絡數據處理能力4 .提高網絡的靈活性和可用性2.2 軟件開發平臺要求Visualc+6.0SQLServer2008C+Build

6、er網絡架構:完全支持TCP/IP協議2.3 軟件項目的開發實施過程管理要求3 .軟件開發3.1 軟件的需求分析1 .DNS負載均衡最早的負載均衡技術是通過DNSE實現的,在DNS為多個地址配置同一個名字,因而查詢這個名字的客戶機將得到其中一個地址,從而使得不同的客戶訪問不同的服務器,達到負載均衡的目的。DNS負載均衡是一種簡單而有效的方法,但是它不能區分服務器的差異,也不能反映服務器的當前運行狀態。2 .代理服務器負載均衡使用代理服務器,可以將請求轉發給內部的服務器,使用這種加速模式顯然可以提升靜態網頁的訪問速度。然而,也可以考慮這樣一種技術,使用代理服務器將請求均勻轉發給多臺服務器,從而達

7、到負載均衡的目的。3 .地址轉換網關負載均衡支持負載均衡的地址轉換網關,可以將一個外部IP地址映射為多個內部IP地址,對每次TCP1接請求動態使用其中一個內部地址,達到負載均衡的目的。4 .協議內部支持負載均衡除了這三種負載均衡方式之外,有的協議內部支持與負載均衡相關的功能,例如HTTPB議中的重定向能力等,HTTPJ!行于TCP連接的最高層。5 .NAT負載土衡NAT簡單地說就是將一個IP地址轉換為另一個IP地址,一般用于未經注冊的內部地址與合法的、已獲注冊的InternetIP地址間進行轉換。適用于解決InternetIP地址緊張、不想讓網絡外部知道內部網絡結構等的場合下。6 .反向代理負

8、載均衡普通代理方式是代理內部網絡用戶訪問internet上服務器的連接請求,客戶端必須指定代理服務器,并將本來要直接發送到internet上服務器的連接請求發送給代理服務器處理。反向代理(ReverseProxy)方式是指以代理服務器來接受internet上的連接請求,然后將請求轉發給內部網絡上的服務器,并將從服務器上得到的結果返回給internet上請求連接的客戶端,此時代理服務器對外就表現為一個服務器。反向代理負載均衡技術是把將來自internet上的連接請求以反向代理的方式動態地轉發給內部網絡上的多臺服務器進行處理,從而達到負載均衡的目的。7 .混合型負載均衡在有些大型網絡,由于多個服務

9、器群內硬件設備、各自的規模、提供的服務等的差異,可以考慮給每個服務器群采用最合適的負載均衡方式,然后又在這多個服務器群間再一次負載均衡或群集起來以一個整體向外界提供服務(即把這多個服務器群當做一個新的服務器群),從而達到最佳的性能。將這種方式稱之為混合型負載均衡。此種方式有時也用于單臺均衡設備的性能不能滿足大量連接請求的情況下。3.2 軟件的概要設計軟件負載均衡解決方案是指在一臺或多臺服務器相應的操作系統上安裝一個或多個附加軟件來實現負載均衡,DNSLoadBalanceCheckPointFirewall-1ConnectControl等,它的優點是基于特定環境,配置簡單,使用靈活,成本低廉

10、,可以滿足一般的負載均衡需求。硬件負載均衡解決方案是直接在服務器和外部網絡間安裝負載均衡設備,這種設備通常稱之為負載均衡器,由于專門的設備完成專門的任務,獨立于操作系統,整體性能得到大量提高,加上多樣化的負載均衡策略,智能化的流量管理,可達到最佳的負載均衡需求。一般而言,硬件負載均衡在功能、性能上優于軟件方式,不過成本昂貴。本地負載均衡能有效地解決數據流量過大、網絡負荷過重的問題,并且不需花費昂貴開支購置性能卓越的服務器,充分利用現有設備,避免服務器單點故障造成數據流量的損失。具有靈活多樣的均衡策略把數據流量合理地分配給服務器群內的服務器共同負擔。即使是再給現有服務器擴充升級,也只是簡單地增加

11、一個新的服務器到服務群中,而不需改變現有網絡結構、停止現有的服務。全局負載均衡主要用于在一個多區域擁有自己服務器的站點,為了使全球用戶只以一個IP地址或域名就能訪問到離自己最近的服務器,從而獲得最快的訪問速度,也可用于子公司分散站點分布廣的大公司通過企業內部互聯網來達到資源統一合理分配的目的。3.3 軟件的詳細設計1 .輪轉法:輪轉算法是所有調度算法中最簡單也最容易實現的一種方法。在一個任務隊列里,隊列的每個成員(節點)都具有相同的地位,輪轉法簡單的在這組成員中順序輪轉選擇。在負載平衡環境中,均衡器將新的請求輪流發給節點隊列中的下一節點,如此連續、周而復始,每個集群的節點都在相等的地位下被輪流

12、選擇。這個算法在DNS®名輪詢中被廣泛使用。輪轉法的活動是可預知的,每個節點被選擇的機會是1/N,因此很容易計算出節點的負載分布。輪轉法典型的適用于集群中所有節點的處理能力和性能均相同的情況,在實際應用中,一般將它與其他簡單方法聯合使用時比較有效。2 .散列法:散列法也叫哈希法(HASH,通過單射不可逆的HASPS數,按照某種規則將網絡請求發往集群節點。哈希法在其他幾類平衡算法不是很有效時會顯示出特別的威力。例如,在前面提到的UD%話的情況下,由于輪轉法和其他幾類基于連接信息的算法,無法識別出會話的起止標記,會引起應用混亂。而采取基于數據包源地址的哈希映射可以在一定程度上解決這個問題

13、:將具有相同源地址的數據包發給同一服務器節點,這使得基于高層會話的事務可以以適當的方式運行。相對稱的是,基于目的地址的哈希調度算法可以用在WebCache集群中,指向同一個目標站點的訪問請求都被負載平衡器發送到同一個Cache服務節點上,以避免頁面缺失而帶來的更新Cache問題。3 .最少連接法:在最少連接法中,平衡器紀錄目前所有活躍連接,把下一個新的請求發給當前含有最少連接數的節點。這種算法針對TCR!接進行,但由于不同應用對系統資源的消耗可能差異很大,而連接數無法反映出真實的應用負載,因此在使用重型Web服務器作為集群節點服務時(例如Apache服務器),該算法在平衡負載的效果上要打個折扣

14、。為了減少這個不利的影響,可以對每個節點設置最大的連接數上限(通過閾值設定體現)。4 .最低缺失法:在最低缺失法中,平衡器長期紀錄到各節點的請求情況,把下個請求發給歷史上處理請求最少的節點。與最少連接法不同的是,最低缺失記錄過去的連接數而不是當前的連接數。5 .最快響應法:平衡器記錄自身到每一個集群節點的網絡響應時間,并將下一個到達的連接請求分配給響應時間最短的節點,這種方法要求使用ICMP包或基于UDPfe的專用技術來主動探測各節點。在大多數基于LAN的集群中,最快響應算法工作的并不是很好,因為LAN中的ICMPfe基本上都在10ms內完成回應,體現不出節點之間的差異;如果在WAN上進行平衡

15、的話,響應時間對于用戶就近選擇服務器而言還是具有現實意義的;而且集群的拓撲越分散這種方法越能體現出效果來。這種方法是高級平衡基于拓撲結構重定向用到的主要方法。6 .加權法:加權方法只能與其他方法合用,是它們的一個很好的補充。加權算法根據節點的優先級或當前的負載狀況(即權值)來構成負載平衡的多優先級隊列,隊列中的每個等待處理的連接都具有相同處理等級,這樣在同一個隊列里可以按照前面的輪轉法或者最少連接法進行均衡,而隊列之間按照優先級的先后順序進行均衡處理。在這里權值是基于各節點能力的一個估計值。3.4 軟件的編碼#include<exception>#include<errno.

16、h>#include<string.h>#include"conn.h"#include"log.h"#include"fdwrapper.h"conn二conn()m_srvfd=-1;m_clt_buf=newcharBUF_SIZE;if(!m_clt_buf)throwstd:exception();m_srv_buf=newcharBUF_SIZE;if(!m_srv_buf)throwstd:exception();reset();conn二conn()deletem_clt_buf;deletem_sr

17、v_buf;voidconn:init_clt(intsockfd,constsockaddr_in&client_addr)m_cltfd=sockfd;m_clt_address=client_addr;voidconn:init_srv(intsockfd,constsockaddr_in&server_addr)m_srvfd=sockfd;m_srv_address=server_addr;voidconn:reset()m_clt_read_idx=0;m_clt_write_idx=0;m_srv_read_idx=0;m_srv_write_idx=0;m_sr

18、v_closed=false;m_cltfd=-1;memset(m_clt_buf,''0',BUF_SIZE);memset(m_srv_buf,'0',BUF_SIZE);RET_CODEconn:read_clt()(intbytes_read=0;while(true)(if(m_clt_read_idx>=BUF_SIZE)(log(LOG_ERF_FILE_,_LINE_,"%s","theclientreadbufferisfull,letserverwrite");returnBUFFER_

19、FULL;bytes_read=recv(m_cltfd,m_clt_buf+m_clt_read_idx,BUF_SIZE-m_clt_read_idx,0);if(bytes_read=-1)(if(errno=EAGAIN|errno=EWOULDBLOCK)(break;returnIOERR;elseif(bytes_read=0)(returnCLOSED;m_clt_read_idx+=bytes_read;return(m_clt_read_idx-m_clt_write_idx)>0)?OK:NOTHING;RET_CODEconn:read_srv()(intbyte

20、s_read=0;while(true)(if(m_srv_read_idx>=BUF_SIZE)(log(LOG_ERF_FILE_,_LINE_,"%s","theserverreadbufferisfull,letclientwrite");returnBUFFER_FULL;bytes_read=recv(m_srvfd,m_srv_buf+m_srv_read_idx,BUF_SIZE-m_srv_read_idx,0);if(bytes_read=-1)(if(errno=EAGAIN|errno=EWOULDBLOCK)(break;

21、returnIOERR;elseif(bytes_read=0)(log(LOG_ERR,_FILE_,_LINE_,"%s","theservershouldnotclosethepersistconnection");returnCLOSED;m_srv_read_idx+=bytes_read;return(m_srv_read_idx-m_srv_write_idx)>0)?OK:NOTHING;RET_CODEconn:write_srv()(intbytes_write=0;while(true)(if(m_clt_read_idx&l

22、t;=m_clt_write_idx)(m_clt_read_idx=0;m_clt_write_idx=0;returnBUFFER_EMPTY;bytes_write=send(m_srvfd,m_clt_buf+m_clt_write_idx,m_clt_read_idx-m_clt_write_idx,0);if(bytes_write=-1)if(errno=EAGAIN|errno=EWOULDBLOCK)returnTRY_AGAIN;)log(LOG_ERR,_FILE_,_LINE_,"writeserversocketfailed,%s",strerro

23、r(errno);returnIOERR;)elseif(bytes_write=0)returnCLOSED;)m_clt_write_idx+=bytes_write;)RET_CODEconn:write_clt()intbytes_write=0;while(true)if(m_srv_read_idx<=m_srv_write_idx)m_srv_read_idx=0;m_srv_write_idx=0;returnBUFFER_EMPTY;)bytes_write=send(m_cltfd,m_srv_buf+m_srv_write_idx,m_srv_read_idx-m_

24、srv_write_idx,0);if(bytes_write=-1)(if(errno=EAGAIN|errno=EWOULDBLOCK)(returnTRY_AGAIN;log(LOG_ERR,_FILE_,_LINE_,"writeclientsocketfailed,%s",strerror(errno);returnIOERR;elseif(bytes_write=0)(returnCLOSED;m_srv_write_idx+=bytes_write;#ifndefFDWRAPPER_H#defineFDWRAPPER_H#include<unistd.h

25、>#include<fcntl.h>#include<sys/epoll.h>intsetnonblocking(intfd)(intold_option=fcntl(fd,F_GETFL);intnew_option=old_option|O_NONBLOCK;fcntl(fd,F_SETFL,new_option);returnold_option;voidadd_read_fd(intepollfd,intfd)(epoll_eventevent;event.data.fd=fd;event.events=EPOLLIN|EPOLLET;epoll_ctl(

26、epollfd,EPOLL_CTL_ADD,fd,&event);setnonblocking(fd);voidadd_write_fd(intepollfd,intfd)epoll_eventevent;event.data.fd=fd;event.events=EPOLLOUT|EPOLLET;epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&event);setnonblocking(fd);voidclosefd(intepollfd,intfd)epoll_ctl(epollfd,EPOLL_CTL_DEL,fd,0);close(fd);voi

27、dremovefd(intepollfd,intfd)epoll_ctl(epollfd,EPOLL_CTL_DEL,fd,0);voidmodfd(intepollfd,intfd,intev)epoll_eventevent;event.data.fd=fd;event.events=ev|EPOLLET;epoll_ctl(epollfd,EPOLL_CTL_MOD,fd,&event);#endif#include<stdio.h>#include<time.h>#include<string.h>#include"log.h&qu

28、ot;staticintlevel=LOG_INFO;staticintLOG_BUFFER_SIZE=2048;staticconstchar*loglevels="emerge!","alert!","critical!","error!","warn!","notice:","info:","debug:");voidset_loglevel(intlog_level)level=log_level;)voidlog(intlog

29、_level,constchar*file_name,intline_num,constchar*format,.)if(log_level>level)return;)time_ttmp=time(NULL);structtm*cur_time=localtime(&tmp);if(!cur_time)return;)chararg_bufferLOG_BUFFER_SIZE;memset(arg_buffer,''0',LOG_BUFFER_SIZE);strftime(arg_buffer,LOG_BUFFER_SIZE1,"%x%X”,c

30、ur_time);printf("%s",arg_buffer);printf("%s:%04d",file_name,line_num);printf("%s",loglevelslog_level-LOG_EMERG);va_listarg_list;va_start(arg_list,format);memset(arg_buffer,'0',LOG_BUFFER_SIZE);vsnprintf(arg_buffer,LOG_BUFFER_SIZE-1,format,arg_list);printf("

31、%sn",arg_buffer);fflush(stdout);va_end(arg_list);)#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<assert.h>#include<stdio.h>#include<unistd.h>#include<errno.h>#include<string.h>#include<fcntl

32、.h>#include<stdlib.h>#include<sys/epoll.h>#include<signal.h>#include<sys/wait.h>#include<sys/stat.h>#include<vector>#include"log.h"#include"conn.h"#include"mgr.h"#include"processpool.h"usingstd:vector;staticconstchar*vers

33、ion="1.0"staticvoidusage(constchar*prog)-flog(LOG_INFO,_FILE_,_LINE_,"usage:%s卜h-vconfig_file”,prog);intmain(intargc,char*argv)charcfg_file1024;memset(cfg_file,''0',100);intoption;while(option=getopt(argc,argv,"f:xvh")!=-1)switch(option)case'x':set_loglev

34、el(LOG_DEBUG);break;case'v':(log(LOG_INFO,_FILE_,_LINE_,"%s%s",argv0,version);return0;case'h':(usage(basename(argv0);return0;case'f:(memcpy(cfg_file,optarg,strlen(optarg);break;case'?':(log(LOGERR,FILE,LINE,"un-recognizedoption%c",option);usage(basenam

35、e(argv0);return1;if(cfg_file0='0')(log(LOG_ERR,FILE,LINE,"%s","pleasespecifiytheconfigfile");return1;intcfg_fd=open(cfg_file,O_RDONLY);if(!cfg_fd)(log(LOG_ERR,_FILE_,_LINE_,"readconfigfilemeterror:%s”,strerror(errno);return1;structstatret_stat;if(fstat(cfg_fd,&re

36、t_stat)<0)(log(LOG_ERR,_FILE_,_LINE_,"readconfigfilemeterror:%s",strerror(errno);return1;char*buf=newcharret_stat.st_size+1;memset(buf,'0',ret_stat.st_size+1);ssize_tread_sz=read(cfg_fd,buf,ret_stat.st_size);if(read_sz<0)(log(LOG_ERR,_FILE_,_LINE_,"readconfigfilemeterror

37、:%s",strerror(errno);return1;vector<host>balance_srv;vector<host>logical_srv;hosttmp_host;memset(tmp_host.m_hostname,'0',1024);char*tmp_hostname;char*tmp_port;char*tmp_conncnt;boolopentag=false;char*tmp=buf;char*tmp2=NULL;char*tmp3=NULL;char*tmp4=NULL;while(tmp2=strpbrk(tmp,

38、"n")(*tmp2+='0'if(strstr(tmp,"<logical_host>")(if(opentag)(log(LOG_ERR,_FILE_,_LINE_,"%sH,"parseconfigfilefailed");return1;opentag=true;elseif(strstr(tmp,"</logical_host>")(if(!opentag)(log(LOG_ERR,_FILE_,_LINE_,"%s","pa

39、rseconfigfilefailed");return1;logical_srv.push_back(tmp_host);memset(tmp_host.m_hostname,'0',1024);opentag=false;elseif(tmp3=strstr(tmp,"<name>")(tmp_hostname=tmp3+6;tmp4=strstr(tmp_hostname,”</name>");if(!tmp4)(log(LOG_ERR,_FILE_,_LINE_,"%s","p

40、arseconfigfilefailed");return1;)*tmp4='0'memcpy(tmphost.mhostname,tmphostname,strlen(tmp_hostname);)elseif(tmp3=strstr(tmp,"<port>")tmp_port=tmp3+6;tmp4=strstr(tmp_port,"</port>");if(!tmp4)10g(LOG_ERR,_FILE_,_LINE_,"%s","parseconfigfilefail

41、ed");return1;)*tmp4='0'tmp_host.m_port=atoi(tmp_port);)elseif(tmp3=strstr(tmp,"<conns>")tmp_conncnt=tmp3+7;tmp4=strstr(tmp_conncnt,"</conns>");if(!tmp4)10g(LOG_ERR,_FILE_,_LINE_,"%s","parseconfigfilefailed");return1;)*tmp4='0't

42、mp_host.m_conncnt=atoi(tmp_conncnt);elseif(tmp3=strstr(tmp,"Listen")(tmp_hostname=tmp3+6;tmp4=strstr(tmp_hostname,":");if(!tmp4)(10g(LOG_ERR,_FILE_,_LINE_,"%s","parseconfigfilefailed");return1;*tmp4+='0'tmp_host.m_port=atoi(tmp4);memcpy(tmp_host.m_host

43、name,tmp3,strlen(tmp3);balance_srv.push_back(tmp_host);memset(tmp_host.m_hostname,'0',1024);tmp=tmp2;if(balance_srv.size()=0|logical_srv.size()=0)(log(LOGERR,FILE,LINE,"%s","parseconfigfilefailed");return1;constchar*ip=balance_srv0.m_hostname;intport=balance_srv0.m_port;i

44、ntlistenfd=socket(PF_INET,SOCK_STREAM,0);assert(listenfd>=0);intret=0;structsockaddr_inaddress;bzero(&address,sizeof(address);address.sin_family=AF_INET;inet_pton(AF_INET,ip,&address.sin_addr);address.sin_port=htons(port);ret=bind(listenfd,(structsockaddr*)&address,sizeof(address);ass

45、ert(ret!=-1);ret=listen(listenfd,5);assert(ret!=-1);/memset(cfg_host.m_hostname,''0',1024);memcpy(cfg_host.m_hostname,"",strlen("");/cfg_host.m_port=54321;cfg_host.m_conncnt=5;processpool<conn,host,mgr>*pool=processpool<conn,host,mgr>:cre

46、ate(listenfd,logical_srv.size();if(pool)pool->run(logical_srv);deletepool;close(listenfd);return0;#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<assert.h>#include<stdio.h>#include<unistd.h>#include<errno.

47、h>#include<string.h>#include<fcntl.h>#include<stdlib.h>#include<sys/epoll.h>#include<signal.h>#include<sys/wait.h>#include<sys/stat.h>#include<exception>#include"log.h"#include"mgr.h"usingstd二pair;intmgr二m_ep011fd=-1;intmgr二conn2

48、sMconstsockaddr_in&address)intsockfd=socket(PF_INET,SOCK_STREAM,0);if(sockfd<0)return-1;)&address,if(connect(sockfd,(structsockaddr*sizeof(address)!=0)close(sockfd);return-1;returnsockfd;mgr:mgr(intepollfd,consthost&srv):m_logic_srv(srv)(m_epollfd=epollfd;intret=0;structsockaddr_inadd

49、ress;bzero(&address,sizeof(address);address.sin_family=AF_INET;inet_pton(AF_INET,srv.m_hostname,&address.sin_addr);address.sin_port=htons(srv.m_port);log(LOG_INFO_FILE_,_LINE,"logcialsrvhostinfo:(%s,%d)”,srv.m_hostname,srv.m_port);for(inti=0;i<srv.m_conncnt;+i)(sleep(1);intsockfd=con

50、n2srv(address);if(sockfd<0)(log(LOGERR,FILE,LINE,"buildconnection%dfailed",i);)else(log(LOG_INFO,FILE,LINE,"buildconnection%dtoserversuccess",i);conn*tmp=NULL;try(tmp=newconn;)catch(.)(close(sockfd);continue;)tmp->init_srv(sockfd,address);m_conns.insert(pair<int,conn*>

51、;(sockfd,tmp);)mgr:mgr()()intmgr:get_used_conn_cnt()(returnm_used.size();)conn*mgr:pick_conn(intcltfd)(if(m_conns.empty()srv(log(LOG_ERR,_FILE,LINE,"%s","notenoughconnectionstoserver");returnNULL;)map<int,conn*>:iteratoriter=m_conns.begin();intsrvfd=iter->first;conn*tmp=

52、iter->second;if(!tmp)(log(LOGERR,FILE,LINE,"%s","emptyserverconnectionobject");returnNULL;m_conns.erase(iter);m_used.insert(pair<int,conn*>(cltfd,tmp);m_used.insert(pair<int,conn*>(srvfd,tmp);add_read_fd(m_epollfd,cltfd);add_read_fd(m_epollfd,srvfd);log(LOG_INFO,_F

53、ILE_,LINE,"bindclientsock%dwithserversock%d",cltfd,srvfd);returntmp;voidmgr:free_conn(conn*connection)(intcltfd=connection->m_cltfd;intsrvfd=connection->m_srvfd;closefd(m_epollfd,cltfd);closefd(m_epollfd,srvfd);m_used.erase(cltfd);m_used.erase(srvfd);connection->reset();m_freed.in

54、sert(pair<int,conn*>(srvfd,connection);voidmgr:recycle_conns()(if(m_freed.empty()(return;for(map<int,conn*>:iteratoriter=mfreed.begin();iter!=m_freed.end();iter+)sleep(1);intsrvfd=iter->first;conn*tmp=iter->second;srvfd=conn2sMtmp->m_srv_address);if(srvfd<0)log(LOG_ERR,_FILE_,_LINE_,"%s","fixconnectionfailed");elselog(LOG_INFO,_FILE_,_LINE_,"%s","fixconnectionsuccess");tmp->init_srv(srvfd,tmp->m_srv_address);m_conns.insert(pair<int,conn*&

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論