首页 文章

为多个HTTP连接重用客户端TCP套接字

提问于
浏览
0

问候所有 .

我正在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'的部分输出(请注意,由于不希望我有多个本地套接字连接到同一个域 - 这些不是每个域并发):

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上使用write / read . 并且它完美地工作但仅一次往返 .

1)如何为每个域的每个HTTP GET写入/读取重用 http_socket_fd ,而无需为每个URL创建新的本地TCP套接字?仅将 http_socket_fd 传递给每个域的每个页面获取调用正是失败的原因 . [危急]

2)如何在每个域范例的每个套接字的这一个线程上向这些服务器发出异步请求?我运行4个并发线程(我的服务器是双线程),即4个不同的并发域提取 . [非关键]

1 回答

  • 0

    通常的做法是为每个连接创建一个客户端套接字 . 在线程之间共享套接字也是一个坏主意 .

    您是否考虑过使用像libcurl这样提供许多高级功能的库,而不是编写自己的HTTP客户端? libcurl站点具有使用多个线程下载内容的a sample program . 另请参阅ZeroMQ,一个高性能的消息传递框架 . ZeroMQ套接字可用于连接多个服务器并有效下载数据 . (见The Guide) .

相关问题