Linux企业级项目实践之网络爬虫(28)——爬虫socket处理
生活随笔
收集整理的這篇文章主要介紹了
Linux企业级项目实践之网络爬虫(28)——爬虫socket处理
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Socket是進程之間交換數據的機制。這些進程即可以是同一臺機器上的,也可以是通過網絡連接起來的不同機器。一旦一個Socket連接建立,那么數據就能夠雙向傳輸,直到其中一端關閉連接。
?
通常,請求數據的應用程序叫做客戶端Client,而為請求服務叫做服務器Server。基本上說,首先,服務器監聽一個端口,并且等待來自客戶端的連接。之后客戶端創建一個,并且嘗試連接服務器。接著,服務器接受了來自客戶端的連接,并且開始交換數據。一旦所有的數據都已經通過socket連接傳輸完畢,那么任意一方都可以關閉連接了。
我們的爬蟲程序只需要client端就夠了。
?
?
int build_connect(int *fd, char *ip, intport) {struct sockaddr_in server_addr;bzero(&server_addr, sizeof(struct sockaddr_in));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(port);if (!inet_aton(ip, &(server_addr.sin_addr))) {return -1;}if ((*fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {return -1;}if (connect(*fd, (struct sockaddr *)&server_addr, sizeof(structsockaddr_in)) < 0) {close(*fd);return -1;}return 0; } void * recv_response(void * arg) {begin_thread();int i, n, trunc_head = 0, len = 0;char * body_ptr = NULL;evso_arg * narg = (evso_arg *)arg;Response *resp = (Response *)malloc(sizeof(Response));resp->header = NULL;resp->body = (char *)malloc(HTML_MAXLEN);resp->body_len = 0;resp->url = narg->url;regex_t re;if (regcomp(&re, HREF_PATTERN, 0) != 0) {/* compile error */SPIDER_LOG(SPIDER_LEVEL_ERROR, "compile regex error");}SPIDER_LOG(SPIDER_LEVEL_INFO, "Crawling url: %s/%s",narg->url->domain, narg->url->path);while(1) {/* what if content-length exceeds HTML_MAXLEN? */n = read(narg->fd, resp->body + len, 1024);if (n < 0) {if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {/*** TODO: Why always recvEAGAIN?* should we deal EINTR*///SPIDER_LOG(SPIDER_LEVEL_WARN,"thread %lu meet EAGAIN or EWOULDBLOCK, sleep", pthread_self());usleep(100000);continue;}SPIDER_LOG(SPIDER_LEVEL_WARN, "Read socket fail: %s",strerror(errno));break;} else if (n == 0) {/* finish reading */resp->body_len = len;if (resp->body_len > 0) {extract_url(&re,resp->body, narg->url);}/* deal resp->body */for (i = 0; i < (int)modules_post_html.size(); i++) {modules_post_html[i]->handle(resp);}break;} else {//SPIDER_LOG(SPIDER_LEVEL_WARN, "read socket ok! len=%d", n);len += n;resp->body[len] = '\0';if (!trunc_head) {if ((body_ptr =strstr(resp->body, "\r\n\r\n")) != NULL) {*(body_ptr+2) = '\0';resp->header =parse_header(resp->body);if(!header_postcheck(resp->header)) {goto leave; /* moduluesfilter fail */}trunc_head = 1;/* cover header */body_ptr += 4;for (i = 0; *body_ptr; i++){resp->body[i] =*body_ptr;body_ptr++;}resp->body[i] = '\0';len = i;}continue;}}}leave:close(narg->fd); /* close socket */free_url(narg->url); /* free Url object */regfree(&re);/* free regex object *//* free resp */free(resp->header->content_type);free(resp->header);free(resp->body);free(resp);end_thread();return NULL; }轉載于:https://www.cnblogs.com/niulanshan/p/6174769.html
總結
以上是生活随笔為你收集整理的Linux企业级项目实践之网络爬虫(28)——爬虫socket处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (王道408考研操作系统)第三章内存管理
- 下一篇: 前端基础-html-表格的结构标签(了解