我在Linux 2.6.29-3.ydl61.3上製作了一個ANSI C多線程www爬蟲(HTTP 1.1兼容),並且進展順利。我在MySQL數據庫中有'000個域來收集頁面。根據需要,我可以在保持活動模式下打開搜尋器中的任何/所有域。我使用POSIX線程,並且沒有任何爭用或數據競賽。
儘管目標服務器似乎準備好允許我爲每個服務器套接字上的頁面發出多個併發或順序請求(因爲每個服務器都如預期的那樣返回'Connection:Keep-Alive'),所以我實際上無法這樣做...我只能每個套接字連接獲取一個頁面......即,我可以通過文件描述符向套接字寫入典型的HTTP GET請求,並讀取響應。然後在那之後,我只能寫信給fd但不能讀取!因此,雖然每個域有多個(一些到幾百個)urls ...似乎我必須不斷重新創建與每個寫入/讀取相同服務器的套接字連接(極度浪費內存而且速度慢),而不是僅創建一個客戶端TCP連接並繼續重複使用fd/socket直到完成域。
參見下面的「netstat的--inet -a」的部分輸出(注意,由於不希望的我有多個本地套接字連接到相同域 - 這些不是每個域併發):
TCP 0 0 gcell1 :38614 x2web02.myhosting.com:http CLOSE_WAIT TCP 0 0 gcell1:34678 x2web02.myhosting.com:http CLOSE_WAIT TCP 0 0 gcell11:34768 x2web02.myhosting.com:http CLOSE_WAIT TCP 0 0 gcell11:56085個www.hihostels .com:http CLOSE_WAIT tcp 0 0 gcell11:34661 x2web02.myhosting.com:http CLOSE_WAIT tcp 0 0 gcell11:34785 x2web02.myhosting.com:http CLOSE_WAIT tcp 0 0 gcell11:46660 67.225.194.54:http CLOSE_WAIT tcp 0 0 gcell11:34697 x2web02.myhosting.com:http CLOSE_WAIT tcp 0 0 gcell11:37510 www.kenic.or.ke:http CLOSE_WAIT tcp 0 0 gcell11:37516 www.kenic.or.ke:http CLOSE_WAIT TCP 0 0 gcell11:34710 x2web02.myhosting.com:http CLOSE_WAIT TCP 0 0 gcell11:34711 x2web02.myhosting.com:http CLOSE_WAIT TCP 0 0 gcell11:46677 67.225.194.54 :HTTP CLOSE_WAIT TCP 0 0 gcell11:56513 www.kenic.or.ke:http CLOSE_WAIT TCP 0 0 gcell11:57560 x2web02.myhosting.com:http CLOSE_WAIT TCP 0 0 gcell11:46634 67.225.194.54:http CLOSE_WAIT TCP 0 0 gcell11:46607 67.225.194.54:http CLOSE_WAIT TCP 0 0 gcell11:46666 67.225.194.54:http CLOSE_WAIT TCP 0 0 gcell11:37526 www.kenic.or.ke:http CLOSE_WAIT TCP 0 0 gcell11:46673 67.225.194.54:http CLOSE_WAIT TCP 0 0 gcell11:34736 x2web02.myhosting.com:http CLOSE_WAIT TCP 0 0 gcell11:57557 x2web02.myhosting.com:http CLOSE_WAIT TCP 0 0 gcell11:56395 www.kenic.or.ke:http CLOSE_WAIT TCP 0 0 gcell11:34714 x2web02.myhosting .com:http CLOSE_WAIT tcp 0 0 gcell11:34669 x2web02.myhosting.com:http CLOSE_WAIT tcp 0 0 gcell11:34767 x2web02.myhosting.com:http CLOSE_WAIT tcp 0 0 gcell11:43381 ip-72-167-251- 99.ip.se:http CLOSE_WAIT
客戶端套接字如下(僅部分碼)
if((http_socket_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP))!=SKMG_FAILURE) //typical
...
fcntl(http_socket_fd,SOCK_NONBLOCK); //set to non-block
...
setsockopt(http_socket_fd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen); //local TCP keep-alive used
...
while(connect(http_socket_fd, (struct sockaddr *)&http_name, sizeof (struct sockaddr_in)) == (-1))
...
return http_socket_fd;
此我只是用寫入/在FD讀出後建立。而且它的功能完美,但只有一次往返旅行。
1)我怎樣才能重複使用http_socket_fd
每個HTTP GET寫/讀每個域,而不需要爲每個url創建一個新的本地TCP套接字?僅僅將http_socket_fd
傳遞給每個域的每個頁面獲取調用正是失敗的工作。 [關鍵]
2)我怎樣才能在這個服務器上的每個域的範例每個套接字的這一個線程的異步請求?我運行4個併發線程(我的服務器是雙線程的),即4個不同的併發域提取。 [NON-CRITICAL]
你可以添加一個示例請求/響應? – Hasturkun 2011-03-22 11:16:13
有人請幫助!爲什麼我不能重複使用http客戶端套接字,因爲我沒有調用close(http_socket_fd)?我不想繼續爲相繼的請求重新創建一個新的客戶端連接套接字。 C中不可能重複使用開放客戶端套接字(已啓用HTTP保持連接)進行連續讀取/寫入?使用Java http://www.mail-archive.com/[email protected]/msg04687.html – EdNdee 2011-04-23 14:20:06