python中select+setblocking和settimeout的对比

首先我设置socket为非阻塞的。然后使用select来监控套接字。

#!/usr/bin/env python
# encoding: utf-8

import socket
import threading
import Queue
import time
import select


class worker(threading.Thread):
    def __init__(self,name,queue):
        self.data=queue
        super(worker,self).__init__(name=name)
    def run(self):
        for i in range(10000):
            self.data.put(i)

class customer(threading.Thread):
    def __init__(self,name,queue):
        super(customer,self).__init__(name=name)
        self.data=queue
    def scan(self,ip,port):
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.setblocking(False)
        #s.settimeout(0.1)
        results=s.connect_ex((ip,port))
        #print results
        a,b,c=select.select([],[s,],[s,],0.1)        #设置超时时间0.1秒,当connect连接成功的时候,代表Tcp3次握手完成,此时变成可写状态
        if b:                                        #如果socket可写,代表了端口是开放的
            print port
        s.close()

    def run(self):
        while True:
            try:
                a=self.data.get(1,5)
            except:
                break
            else:
                ip='220.181.136.241'
                self.scan(ip,a)
def main():
    start=time.time()
    queue=Queue.Queue()
    pool=[]
    worke=worker('firebroo',queue)
    worke.start()
    for i in range(100):
        a=customer('firebroo',queue)
        pool.append(a)
    for i in pool:
        i.start()
    worke.join()
    for i in pool:
        i.join()
    print time.time()-start
    del pool[:]
if __name__=='__main__':
    main()

大概花费17.5秒执行完毕。下面我使用settimeout。

#!/usr/bin/env python
# encoding: utf-8

import socket
import threading
import Queue
import time
import select


class worker(threading.Thread):
    def __init__(self,name,queue):
        self.data=queue
        super(worker,self).__init__(name=name)
    def run(self):
        for i in range(10000):
            self.data.put(i)

class customer(threading.Thread):
    def __init__(self,name,queue):
        super(customer,self).__init__(name=name)
        self.data=queue
    def scan(self,ip,port):
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        #s.setblocking(False)
        s.settimeout(0.1)                                #为了和前面保持一致,当然得设置0.1秒
        results=s.connect_ex((ip,port))
        if results==0:                                   #connect_ex中0代表端口开放,3次握手完成
            print port
        s.close()

    def run(self):
        while True:
            try:
                a=self.data.get(1,5)
            except:
                break
            else:
                ip='220.181.136.241'
                self.scan(ip,a)
def main():
    start=time.time()
    queue=Queue.Queue()
    pool=[]
    worke=worker('firebroo',queue)
    worke.start()
    for i in range(100):
        a=customer('firebroo',queue)
        pool.append(a)
    for i in pool:
        i.start()
    worke.join()
    for i in pool:
        i.join()
    print time.time()-start
    del pool[:]
if __name__=='__main__':
    main()

时间大概是17.4。这两个测试结果应该可以说是一样的,难免会有误差。

情况看起来差不多,但是我更加推荐使用第一种做法。

你可能感兴趣的:(python中select+setblocking和settimeout的对比)