码迷,mamicode.com
首页 > 其他好文 > 详细

异步非阻塞socket的实现

时间:2017-08-31 23:08:08      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:代码示例   send   返回   不同   原理   开始   实例化   异步   存在   

在学习使用scrapy爬虫框架之前,需要了解一些基础原理

  我们知道HTTP请求是基于socket模块进行发送和接受的,但是socket套接字的在使用的中存在着阻塞,不利用爬虫的高性能运行,所以我们就需要对框架进行一些高性能设置,使用select模块,检测socket请求的IO操作,实现对socket的高性能运行:

以下是代码示例:

import socket
import select


class Request(object):
    ‘‘‘
    request类的定义是应对请求的连接不同时,做的低耦合操作
    ‘‘‘
    def __int__(self,sock,info):
        self.sock=sock
        self.info=info

    def fileno(self):
        ‘‘‘
        因为select模块在检测IO操作但是针对socket对象,该对象中必须有fileno方法才能调用,
        因此需要我们自己定义一个request类,在类下包含fileno方法
        :return:
        ‘‘‘
        return self.sock.fileno()



class Mysocket(object):
    def __int__(self):
        ‘‘‘
        初始化两个列表,存储socket对象
        :return:
        ‘‘‘
        self.sock_list=[]
        self.conns=[]


    def add_request(self,req_info):
        ‘‘‘
        创建请求
        :param req_info: {‘host‘:‘www.baidu.com‘,‘port‘:80}
        :return:
        ‘‘‘
        sock=socket.socket()
        sock.setblocking(False)#设置socket为非阻塞状态
        try:
            sock.connect((req_info[host],req_info[post]))
        except BaseException as e:
            pass
        #使用try方法防止sock在非阻塞状态下报错

        obj=Request(sock,req_info)#示例话Request类,此类就是socket实例化的对象
        self.sock_list.append(obj)
        self.conns.append(obj)

    def run(self):
        ‘‘‘
        开始事件循环,检测:连接是否成功,是否有数据返回
        :return:
        ‘‘‘
        while True:
            r,w,e=select.select(self.sock_list,self.conns,[],0.05)
            #select。select([socket对象,]),可以是任何对象,但是对象一定要有
            #fileno方法,所以需要自己去定义request类
            #在此处就调用request对象

            #seclet参数w数值就是检测请求是否成功
            for obj in w:
                #检查obj.request对象
                data="GET %s http/1.1\r\nhost:%s\r\n\r\n" %(obj.info[path],obj.info[host])
                obj.sock.send(data.encode(utf8))
                self.conns.remove(obj)#该连接在成功请求过后,为防止重复发送请求,需请求列表中将其删除
                
                
            #数据返回,接受到数据
            for obj in r:
                response=obj.sock.recv(8096)
                obj.info["callback"](response)
                self.sock_list.remove(obj)

from .. import Mysocket
def data(response):
    ‘‘‘
    回调函数,对返回的数据进行操作
    :param response:
    :return:
    ‘‘‘
    print(response)

def file(response):
    ‘‘‘
    回调函数,对返回数值的第二种操作方式
    :param response:
    :return:
    ‘‘‘
    print(response)

url_list = [
    {host: www.baidu.com, port: 80, path: /,callback: data},
    {host: www.cnblogs.com, port: 80, path: /index.html,callback: file},
    {host: www.bing.com, port: 80, path: /,callback: data},
]

obj=Mysocket()
for item in url_list:
    obj.add_request(item)

obj.run()

 

异步非阻塞socket的实现

标签:代码示例   send   返回   不同   原理   开始   实例化   异步   存在   

原文地址:http://www.cnblogs.com/lzh1118/p/7460822.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!