最近在写一个爬虫项目,启动了多个线程去爬取网站的公开数据(这里说一下,多线程爬虫对被爬取的网站压力比较大,可能会导致目标网站被搞崩溃,所以最好注意一下不要起太多线程,而且也容易被反爬虫拦截封锁IP),但是有个疑问就是,我多个线程去爬取数据,目标网站返回的响应为什么不会产生混乱呢,比如ABC三个线程去请求数据,结果A线程的响应返回给了B线程,B线程的响应又返回给了C线程。所以看了一下TCP协议的博客,写下这篇文章。
首先,我的爬虫程序是用Java写的,用httpclient发请求,而http是在tcp的基础上封装的,爬虫用多个线程爬数据就会有多个tcp连接到目标网站。而系统是怎么标识,或者说区分每一个tcp连接才不会导致我上面说的数据混乱的问题呢?TCP用一个4四元组来唯一标识一个连接:{local ip, local port,remote ip,remote port}。也就是:本地ip地址,本地端口,远程ip地址,远程端口。在我这个爬虫程序里面就是:本机ip,本机端口,服务器ip,服务器端口。在这里,对我的爬虫程序而言,服务器ip和服务器端口肯定是一样的,但是每开一个线程去爬取数据,都会自动选择一个本地空闲的端口(除非你自己编写代码的时候手动指定了端口)来标识这个tcp连接。这样服务器响应的时候就会返回到不同的端口,这样就区分开了。
简而言之就是,多线程爬虫会有多个tcp连接,而这多个tcp连接会用不同的本机端口来区分开,所以不会产生数据混乱的问题。
在探究这个问题的时候也学到了服务器和客户端分别最大可以支持多少个tcp连接。