亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 3866 | 回復(fù): 6
打印 上一主題 下一主題

HTTP代理系統(tǒng)的問(wèn)題 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2011-07-13 15:35 |只看該作者 |倒序?yàn)g覽
本帖最后由 ohyeahbbs 于 2011-07-13 15:38 編輯

小弟跟著老師在弄一個(gè)HTTP代理系統(tǒng);搗鼓了一個(gè)星期終于容易可以代理成功了,卻發(fā)現(xiàn)html的頁(yè)面只能打開(kāi)一兩個(gè),然后用top查看Linux系統(tǒng)資源發(fā)現(xiàn)代理占據(jù)資源達(dá)到了七八十%。
哪位大蝦幫忙看看,優(yōu)化一下。。。
采用線程綁定文件描述字的方法。。。。
代碼如下:
  1. 1,proxy:

  2. #include "threadpool/include/threadpool.hpp"
  3. #include<iostream>
  4. #include<string.h>// char *strerror(int errnum);errnum(通常就是errno)
  5. #include<sys/socket.h>
  6. #include<errno.h>
  7. #include<arpa/inet.h>
  8. #include<unistd.h>
  9. #include<signal.h>
  10. #include<stdlib.h>

  11. #define BACKLOG 128

  12. using namespace std;

  13. int         httpproxy(void *fd);

  14. int        listenfd;                //文件(套接字socket)描述符
  15. volatile bool        gIsRunning;        //volatile表示把gIsRunning添加到內(nèi)存中

  16. boost::threadpool::pool threadPool; //利用線程池創(chuàng)建線程并設(shè)線程大小為66

  17. /* 關(guān)閉proxy */
  18. void sysclosed(int signal)   
  19. {
  20.         gIsRunning = false;
  21.         cout<<"Waiting for proxy threads..."<<endl;
  22.             threadPool.wait();
  23.         close(listenfd);
  24.         cout<<"proxy is closed"<<endl;
  25. }

  26. int main()
  27. {
  28.         int                        *connfd;        //accept所返回的文件(套接字)描述符                       
  29.         socklen_t                client;
  30.         struct sockaddr_in        cliaddr,servaddr;
  31.         gIsRunning = true;

  32.         system("service iptables restart");
  33.         sleep(3);

  34.         /* 端口80重點(diǎn)向?yàn)楸镜囟丝?997 */
  35.           system("iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 9997");
  36.         cout<<"iptables prerouting success"<<endl;

  37.         /* 創(chuàng)立并監(jiān)聽(tīng)socket */
  38.         cout<<"Start the server..."<<endl;
  39.         if((listenfd = socket(AF_INET, SOCK_STREAM, 0))<0 )
  40.         {
  41.                 cout<<"Creat the socket error!"<<endl;
  42.                 exit(-1);       
  43.         }
  44.         else cout<<"Creat the socket success"<<endl;
  45.        
  46.         memset(&servaddr,0,sizeof(servaddr));
  47.         servaddr.sin_addr.s_addr  = INADDR_ANY;
  48.         servaddr.sin_family            = AF_INET;
  49.         servaddr.sin_port        = htons(9997);
  50.                
  51.         /* 綁定任意IP及特定端口 */
  52.         if(bind(listenfd,(struct sockaddr *)&servaddr, sizeof(servaddr)) <0 )
  53.         {
  54.                 cout<<"Bind error"<<strerror(errno)<<endl;
  55.         }
  56.         else cout<<"Bind the port success"<<endl;

  57.         /* 在socket上監(jiān)聽(tīng)連接 */
  58.         if(listen(listenfd, BACKLOG) != 0 )
  59.         {
  60.                 cout<<"Listen error"<<strerror(errno)<<endl;
  61.         }
  62.         else cout<<"Listen is running..."<<endl;
  63.        
  64.         threadPool.size_controller().resize(66);
  65.           
  66.         signal(SIGINT, sysclosed);

  67.         /* 循環(huán)接受TCP連接 */       
  68.         for( ; gIsRunning == 1 ; )
  69.         //while(gIsRunning)
  70.         {
  71.                 client = sizeof(cliaddr);
  72.                 connfd = (int*)malloc(sizeof(int));

  73.                 /* accept所返回的文件描述符是新的套接字描述符和原始套接字listenfd具有相同的套接字類(lèi)型和地址簇
  74.                  * 傳給accept的原始套接字沒(méi)有關(guān)聯(lián)到這個(gè)連接,而是繼續(xù)保持可用狀態(tài)并接受其他連接請(qǐng)求 */
  75.                 if((*connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &client))<0)
  76.                 {
  77.                
  78.                         /*accetp()是慢系統(tǒng)調(diào)用,在信號(hào)產(chǎn)生時(shí)會(huì)中斷其調(diào)用并將
  79.                          errno變量設(shè)置為EINTR,此時(shí)應(yīng)重新調(diào)用accept()。*/
  80.                         if( errno == EINTR )
  81.                         {
  82.                                 cout<<"Accept error (EINTR):"<<strerror(errno)<<endl;
  83.                                 continue;
  84.                         }
  85.                                else
  86.                                {
  87.                                 cout<<"Accept error:"<<strerror(errno)<<endl;
  88.                                 exit(1);
  89.                         }
  90.                 }
  91.                 else cout<<"Start the http connect!"<<endl;

  92.                 /* 把a(bǔ)ccept返回的套接字描述符與線程httpproxy綁定 */
  93.                 threadPool.schedule(boost::bind(&httpproxy, (void *)connfd));

  94.         }
  95. }


  96. 2,forwarddata:

  97.                 #include<sys/select.h>
  98. #include<iostream>
  99. #include<string.h>
  100. #include<sys/socket.h>
  101. #include<errno.h>
  102. #include<arpa/inet.h>
  103. #include <linux/kernel.h>
  104. #include <linux/netfilter_ipv4.h>

  105. #define MAXLINE 4096  

  106. /* 聲明外部變量gIsRunning */
  107. extern volatile bool gIsRunning;

  108. using namespace std;

  109. int forwarddata(int connfd, int remotefd);

  110. int max(int a, int b)
  111. {
  112.         return a>b?a:b;
  113. }

  114. int httpproxy(void *fd)
  115. {
  116.         int                 connfd,remotefd,port;
  117.         socklen_t        len;
  118.         char                buff[100+1];
  119.         const char *        ipaddr;

  120.         struct sockaddr_in        remoteserv;
  121.         struct sockaddr_in        dest;

  122.         connfd = *((int *)fd);
  123.         free(fd);

  124.         /* 獲取連接的目的IP和PORT */
  125.         memset(buff, 0x00, sizeof(buff));
  126.         len =sizeof(dest);
  127.         memset(&dest, 0, len);
  128.         if(getsockopt(connfd, SOL_IP, SO_ORIGINAL_DST, &dest, &len)< 0)
  129.         {
  130.                 cout<<"Getsockopt error:"<<strerror(errno)<<endl;
  131.                 return -1;
  132.         }
  133.         else
  134.         {
  135.                 ipaddr = inet_ntop(AF_INET, &dest.sin_addr, buff, sizeof(buff));
  136.                 port   = ntohs(dest.sin_port);
  137.                 cout<<"Iptables transparent destination:"<<ipaddr<<":"<<port<<endl;
  138.         }

  139.         cout<<"buff="<<buff<<" "<<"port="<<port<<endl;

  140.         /* 創(chuàng)建到服務(wù)器socket */
  141.         if((remotefd = socket(AF_INET, SOCK_STREAM, 0))<0)
  142.         {
  143.                 cout<<"Remote error:"<<strerror(errno)<<endl;
  144.                 return -1;
  145.         }
  146.         memset(&remoteserv, 0x00, sizeof(remoteserv));
  147.         remoteserv.sin_family = AF_INET;
  148.         remoteserv.sin_port   = htons(ntohs(dest.sin_port));
  149.         inet_pton(AF_INET, buff, &remoteserv.sin_addr);
  150.        
  151.         /* 按目的地址建立連接 */
  152.         if(connect(remotefd, (struct sockaddr *)&remoteserv, sizeof(remoteserv))<0)
  153.         {
  154.                 cout<<"Connect remote server error:"<<strerror(errno)<<endl;
  155.                 //goto STOP_THREAD;
  156.                 return -1;
  157.         }
  158.         else
  159.         {       
  160.                 /* 處理connfd和remotefd的數(shù)據(jù)交換 */
  161.                 forwarddata(connfd, remotefd);
  162.         }
  163.         return 0;
  164. }

  165. int forwarddata(int connfd, int remotefd)
  166. {
  167.         int        maxfdp1;
  168.         int        ret, n;
  169.         char        buff[MAXLINE];
  170.         fd_set        rset;                 //分配一個(gè)狀態(tài)描述符類(lèi)型的變量
  171.         struct timeval val;
  172.         val.tv_sec = 10;
  173.         val.tv_usec = 0;

  174.         FD_ZERO(&rset);                //將一個(gè)指定的fd_set變量的所有位設(shè)置為0.
  175.         ret = 0;
  176.        
  177.         /* 循環(huán)地從客戶端讀,向服務(wù)端寫(xiě);從服務(wù)器端讀,向客戶端寫(xiě) */
  178.         for( ; gIsRunning==1 ; )
  179.         //printf("test3=%d\n", gIsRunning);
  180.         //while(gIsRunning)
  181.         {
  182.                 /* 調(diào)用FD_SET設(shè)置一個(gè)fd_set變量的指定位。添加描述符到描述符集合*/
  183.                 FD_SET(connfd, &rset);
  184.                 FD_SET(remotefd, &rset);
  185.        
  186.                 /* 因?yàn)槊枋龇幪?hào)從0開(kāi)始,所以要在最大描述符編號(hào)值上加1 */
  187.                 maxfdp1 = max(connfd, remotefd) + 1;
  188.                
  189.                 /* 返還值-1表示出錯(cuò) */
  190.                 if((n = select(maxfdp1, &rset, NULL, NULL, &val))<0)
  191.                 {
  192.                         cout<<"Select serror!"<<endl;
  193.                         break;
  194.                 }
  195.                 /* 判斷是否為超時(shí)返回 */
  196.                 if( n == 0 )
  197.                         continue;

  198.                 /* 從客戶端讀recv(client) */
  199.                 if(FD_ISSET(connfd, &rset)) //測(cè)試一指定位是否設(shè)置,檢查FD集合中FD是否準(zhǔn)備好
  200.                 {
  201.                         memset(buff, 0x00, sizeof(buff));
  202.                         ret = recv(connfd, buff, MAXLINE, 0);
  203.                         if(ret > 0)
  204.                         {
  205.                                 cout<<"Client to server..."<<endl;

  206.                                 /* 向服務(wù)器端寫(xiě)send(server) */
  207.                                 ret = send(remotefd, buff, ret, 0);
  208.                                 if(ret == -1)
  209.                                 {
  210.                                         cout<<"Send data to real server error"<<endl;
  211.                                         break;
  212.                                 }
  213.                         }
  214.                         /* 沒(méi)讀到數(shù)據(jù)關(guān)閉連接 */
  215.                         else if(ret == 0)
  216.                         {
  217.                                 break;
  218.                         }
  219.                         /* 從客戶端接受數(shù)據(jù)錯(cuò)誤 */
  220.                         else
  221.                         {
  222.                                 break;
  223.                         }
  224.                 }

  225.                 /* 從服務(wù)器端讀recv(server) */
  226.                 if(FD_ISSET(remotefd, &rset))
  227.                 {
  228.                         memset(buff, 0x00, sizeof(buff));
  229.                         ret = recv(remotefd, buff, MAXLINE, 0);
  230.                         if(ret > 0)
  231.                         {
  232.                                 cout<<"Remote to client..."<<endl;

  233.                                 /* 向客戶端寫(xiě)send(client) */
  234.                                 ret = send(connfd, buff, ret, 0);
  235.                                 if(ret == -1)
  236.                                 {
  237.                                         cout<<"Send data to client error"<<endl;
  238.                                         break;
  239.                                 }
  240.                         }
  241.                         /* 沒(méi)讀到數(shù)據(jù)關(guān)閉連接 */
  242.                         else if(ret == 0)
  243.                         {
  244.                                 break;
  245.                         }
  246.                         /* 從客戶端接受數(shù)據(jù)錯(cuò)誤 */
  247.                         else
  248.                         {
  249.                                 break;
  250.                         }
  251.                 }

  252.         }
  253.         return 0;

  254. }
復(fù)制代碼

論壇徽章:
0
2 [報(bào)告]
發(fā)表于 2011-07-13 15:39 |只看該作者
坐等高人··指點(diǎn)····

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2011-07-13 16:04 |只看該作者

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2011-07-13 16:08 |只看該作者
val.tv_sec = 10;
val.tv_usec = 0;
放到select函數(shù)前面就成。。。

論壇徽章:
0
5 [報(bào)告]
發(fā)表于 2011-07-13 17:29 |只看該作者
val.tv_sec = 10;
val.tv_usec = 0;
放到select函數(shù)前面就成。。。
xiboboy123 發(fā)表于 2011-07-13 16:08


嗯嗯,top  中的pproxy代理占用資源的確有明顯大量的減少,可以html代理連接的頁(yè)面依然只能代理2~3個(gè)頁(yè)面,點(diǎn)擊多個(gè)時(shí)打不開(kāi)·········

論壇徽章:
0
6 [報(bào)告]
發(fā)表于 2011-07-13 17:45 |只看該作者
是不是線程綁定的資源沒(méi)有釋放導(dǎo)致不能打開(kāi)多個(gè)頁(yè)面的鏈接吖。。。。??

如果后面我不采用線程來(lái)綁定文件秒數(shù)字來(lái)處理調(diào)用httpproxy函數(shù)的調(diào)用,
而采用進(jìn)程來(lái)調(diào)用就不會(huì)產(chǎn)生不能打開(kāi)多個(gè)頁(yè)面的問(wèn)題。。。這是為什么呢???
進(jìn)程替換線程代碼如下:
要替換的:
  1.       /* 把a(bǔ)ccept返回的套接字描述符與線程httpproxy綁定 */
  2.                 threadPool.schedule(boost::bind(&httpproxy, (void *)connfd));
復(fù)制代碼
替換為:
  1. /* 創(chuàng)建子進(jìn)程,處理請(qǐng)求 */
  2.                 if((pid = fork()) > 0)
  3.                 {
  4.                         /* 父進(jìn)程處理 */
  5.                         free(connfd);
  6.                         continue ;
  7.                 }
  8.                 else if(pid == 0)
  9.                 {
  10.                         /* 子進(jìn)程處理 */
  11.                         close(listenfd);
  12.                         cout<<"Start the http connect!"<<endl;
  13.                         httpproxy((void *)connfd);
  14.                         exit(0);
  15.                 }
  16.                 else if(pid < 0)
  17.                 {
  18.                         cout<<"Creat the child process fail! "<<endl;
  19.                         exit(2);
  20.                 }
  21.                 close(listenfd);
復(fù)制代碼
這樣就可以打開(kāi)多個(gè)網(wǎng)頁(yè)了······不懂真不懂這是為啥????線程不是用完自動(dòng)釋放,重復(fù)利用的麼??
望大蝦指點(diǎn)·····

論壇徽章:
0
7 [報(bào)告]
發(fā)表于 2011-07-14 09:55 |只看該作者
是不是由這個(gè)原因啊???有木有大蝦啊??
由于程序用select等待連接完成,可以設(shè)置一個(gè)select等待時(shí)間限制,從而縮短connect超時(shí)時(shí)間。多數(shù)實(shí)現(xiàn)中,connect的超時(shí)時(shí)間在75秒到幾分鐘之間。有時(shí)程序希望在等待一定時(shí)間內(nèi)結(jié)束,使用非阻塞connect可以防止阻塞75秒,在多線程網(wǎng)絡(luò)編程中,尤其必要。   例如有一個(gè)通過(guò)建立線程與其他主機(jī)進(jìn)行socket通信的應(yīng)用程序,如果建立的線程使用阻塞connect與遠(yuǎn)程通信,當(dāng)有幾百個(gè)線程并發(fā)的時(shí)候,由于網(wǎng)絡(luò)延遲而全部阻塞,阻塞的線程不會(huì)釋放系統(tǒng)的資源,同一時(shí)刻阻塞線程超過(guò)一定數(shù)量時(shí)候,系統(tǒng)就不再允許建立新的線程(每個(gè)進(jìn)程由于進(jìn)程空間的原因能產(chǎn)生的線程有限),如果使用非阻塞的connect,連接失敗使用select等待很短時(shí)間,如果還沒(méi)有連接后,線程立刻結(jié)束釋放資源,防止大量線程阻塞而使程序崩潰。
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專(zhuān)區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP