2011-03-22 4 views
0

인사말 모두.여러 HTTP 연결을 위해 클라이언트 TCP 소켓 재사용

Linux 2.6.29-3.ydl61.3에서 ANSI C 멀티 스레드 www-crawler (HTTP 1.1 호환)를 만들고 있습니다. 상당히 발전했습니다. 나는 페이지를 수집하기 위해 MySQL 데이터베이스에 도메인 000 개를 가지고있다. 원하는대로 크롤러의 모든/모든 도메인을 연결 유지 모드로 열 수 있습니다. POSIX 스레딩을 사용하며 경합이나 데이터 경주가 전혀 없습니다.

각 서버가 'Connection : Keep-Alive'를 예상대로 반환하기 때문에 대상 서버에서 각 서버 소켓의 페이지에 대해 여러 동시 또는 순차 요청을 실행할 수있는 것처럼 보이지만 실제로 그렇게 할 수는 없습니다 ... 소켓 연결 당 하나의 페이지 만 가져올 수 있습니다. 즉, 파일 설명자를 통해 소켓에 일반적인 HTTP GET 요청을 작성하고 응답을 읽을 수 있습니다. 그런 다음 바로 그 후에, 나는 fd로만 쓸 수 있지만 더 이상 읽을 수는 없습니다! 따라서 도메인 당 여러 개의 URL을 가지고있는 동안 ... 하나의 클라이언트 TCP 연결을 작성하기보다는 각각의 쓰기/읽기 (매우 낭비하고 느린)마다 동일한 서버에 대한 소켓 연결을 다시 만들어야합니다. 도메인과 함께 할 때까지 fd/socket을 재사용하십시오.

가 'NETSTAT --inet -a'의 부분 출력 아래 참조 (I가 같은 도메인에 여러 로컬 소켓 연결을 같은 원치 않는이 있습니다 -이 도메인 당 동시 없음) :

TCP 0 0 gcell1 : 38,614 x2web02.myhosting.com:http의 CLOSE_WAIT TCP 0 0 gcell1 : 34,678 x2web02.myhosting.com:http의 CLOSE_WAIT TCP 0 0 gcell11 : 34,768 x2web02.myhosting.com:http의 CLOSE_WAIT TCP 0 0 gcell11 : 56,085 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 : 46,660 67.225.194.54:http CLOSE_WAIT TCP 0 0 gcell11 : 34,697 x2web02.myhosting.com:http의 CLOSE_WAIT TCP 0 0 gcell11 : 37,510 www.kenic.or.ke:http의 CLOSE_WAIT TCP 0 0 gcell11 : 37516 www.kenic.or.ke:http CLOSE_WAIT TCP 0 0 gcell11 : 34,710 x2web02.myhosting.com:http의 CLOSE_WAIT TCP 0 0 gcell11 : 34,711 x2web02.myhosting.com:http의 CLOSE_WAIT TCP 0 0 gcell11 : 46,677 67.225.194.54 : HTTP CLOSE_WAIT TCP 0 0 gcell11 : 56,513 www.kenic.or.ke:http의 CLOSE_WAIT TCP 0 0 gcell11 : 57,560 x2web02.myhosting.com:http의 CLOSE_WAIT TCP 0 0 gcell11 : 46,634 67.225.194.54:http CLOSE_WAIT TCP 0 0 gcell11 : 46607 67.225.194.54:http CLOSE_WAIT TCP 0 0 gcell11 : 46,666 67.225.194.54:http CLOSE_WAIT TCP 0 0 gcell11 : 37,526 www.kenic.or.ke:http의 CLOSE_WAIT TCP 0 0 gcell11 : 46,673 67.225.194.54:http CLOSE_WAIT TCP 0 0 gcell11 : 34,736 x2web02.myhosting.com:http CLOSE_WAIT TCP 0 0 gcell11 : 57,557 x2web02.myhosting.com:http의 CLOSE_WAIT TCP 0 0 gcell11 : 56,395 www.kenic.or.ke:http의 CLOSE_WAIT TCP 0 0 gcell11 : 34,714 x2web02.myhosting .COM : HTTP CLOSE_WAIT TCP 0 0 gcell11 : 34,669 x2web02.myhosting.com:http의 CLOSE_WAIT TCP 0 0 gcell11 : 34,767 x2web02.myhosting.com:http의 CLOSE_WAIT TCP 0 0 gcell11 : 43381 IP-72-167-251- 99.ip.se:http CLOSE_WAIT

(210)

클라이언트 소켓 (부분적인 코드) 난 그냥 FD에 읽기 쓰기/사용이 후

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; 

다음과 같이 생성됩니다. 그리고 그것은 단 한 번의 왕복 여행을 위해 완벽하게 작동합니다.

1) 각 URL에 대해 새로운 로컬 TCP 소켓을 만들지 않고 도메인 당 각 HTTP GET 쓰기/읽기에 대해 http_socket_fd을 어떻게 다시 사용할 수 있습니까? 도메인 당 페이지 가져 오기 호출마다 http_socket_fd을 전달하는 것만으로도 작업에 실패한 것입니다. [CRITICAL]

2) 도메인 당 패러다임 당 소켓 당 하나의 스레드에서 비동기 요청을 어떻게 만들 수 있습니까? 4 개의 동시 스레드 (내 서버는 이중 스레드)를 실행합니다. 즉 4 개의 동시 도메인 가져 오기가 실행됩니다. [NON-CRITICAL]

+0

예제 요청/응답을 추가 할 수 있습니까? – Hasturkun

+0

누군가가 도와주세요! close (http_socket_fd)를 호출하지 않아서 왜 http 클라이언트 소켓을 재사용 할 수 없습니까? 연속적인 요청을 위해 동일한 호스트에 새로운 클라이언트 연결 소켓을 다시 생성하고 싶지 않습니다. C에서 연속적으로 읽기/쓰기를 위해 열린 클라이언트 소켓 (이미 HTTP 연결 유지가 활성화되어 있음)을 재사용 할 수 있습니까? Java with http://www.mail-archive.com/[email protected]/msg04687.html – EdNdee

답변

0

일반적으로 연결 당 하나의 클라이언트 소켓을 만드는 것입니다. 스레드간에 소켓을 공유하는 것도 좋지 않습니다.

자신의 HTTP 클라이언트를 작성하는 대신 많은 고급 기능을 제공하는 libcurl과 같은 라이브러리를 사용 해본 적이 있습니까? libcurl 사이트에는 다중 스레드를 사용하여 콘텐츠를 다운로드하는 a sample program이 있습니다. 또한 고성능 메시징 프레임 워크 인 ZeroMQ을 살펴보십시오. ZeroMQ 소켓을 사용하여 여러 서버에 연결하고 효율적으로 데이터를 다운로드 할 수 있습니다. (The Guide 참조).

+0

Vijay, 제 3 자 라이브러리 사용에 대한 신속한 응답과 제안에 감사드립니다. 수정, 스레드를 통해 소켓을 전혀 공유하지 않습니다! 나는 분명히 그렇게 말했다 ... "도메인 당 패러다임 당 하나의 쓰레드"풀에있는 4 개의 쓰레드의 각 쓰레드는 하나의 소켓만을 처리하고 각 소켓은 하나의 도메인에만 연결된다. 내 질문은 각 도메인에 대한 모든 연속 연결에 대해이 정확한 접근 방식을 유지하는 것과 관련이 있습니다. 3rdp 라이브러리에 관해서는 드문 경우이지만 블랙 박스를 다루지 않고 특정 이유로 코드의 절대적인 제어가 필요합니다. – EdNdee