SOCK4\5的代理服务器

# -*- coding: GBK -*-
"""这是个SOCK4\5的代理服务器,我暂时完成了TCP的部分,
UPD代理功能未能实现,但是已经可以完成绝大多数的代理任务
IE,Firefox,QQ,讯雷均测试通过,且cpu占用情况良好.
"""
debug=True
remote=False
running=True
import asyncore, sys
import _winreg as reg
import socket
from socket import AF_INET,SOCK_STREAM
from struct import *
import datetime
logfile=open('sockslog.txt','a')
logfile.writelines((str(datetime.datetime.now()),))

def printd(*data):
    if debug:
        for x in data:
            print x,
            logfile.writelines((str(x),))
        print '\r'
def ordp(str):
    for x in str:
        pass
        printd(ord(x))
def tryconnect(addr):
    sock=socket.socket()
    sock.settimeout(0.5)
    if sock.connect_ex(addr)!=0:
        printd("connect failed.")
        sock.close()
        return None
    else:
        sock.setblocking(0)
        printd('connect ok')
        return sock

class listener(asyncore.dispatcher):
    def __init__(self,port,n):
        asyncore.dispatcher.__init__(self)
        self.create_socket(AF_INET, SOCK_STREAM)
        self.bind(('',listenport))
        self.listen(n)
        printd('begin listen.....')
    def handle_accept(self):
        sock,addr=self.accept()
        printd('has client..')
        s=server(sock)
        s.buffer=''
        try:
            s.pair.buffer=''
        except:
            pass
class baseconn(asyncore.dispatcher):
    def handle_close(self):
        printd(self.name,)
        self.close()
        try:
            self.pair.close()
            printd(self.pair.name)
        except:
            pass
        printd('closed')
        printd(asyncore.socket_map)
    def handle_read(self):
        if self._fileno:
            data=self.recv(8192)
            self.pair.buffer+=data
            printd(self.name,'read',len(data))#,'\n',data)
            self.pair.handle_write()
    def handle_write(self):
        if self._fileno:
            sent = self.send(self.buffer)
            printd(self.name,'sented',sent)#,'\n',self.buffer[:sent])
            self.buffer = self.buffer[sent:]
    def writable(self):
        return len(self.buffer) > 0
    def readable(self):#防止缓存过大,引起cpu高占用
        return len(self.pair.buffer) < 409600
    def handle_expt(self):
        printd(asyncore.compact_traceback())
    def handle_error(self):
        printd(asyncore.compact_traceback())
        self.handle_close()
class server(baseconn):
    def __init__(self, sock):
        baseconn.__init__(self,sock)
        self.name='server '+str(self._fileno)+str(self.socket.getpeername())
        self.buffer=''
        self.socket.settimeout(1)
        try:
            VER=ord(self.socket.recv(1))
            if VER==5:#SOCKS V5 实现部分(地址解读)
                NMETHODS,METHODS=unpack('BB',self.socket.recv(2))
                self.socket.send('\x05\x00')
                _VER,CMD,RSV=unpack('BBB',self.socket.recv(3))
                if CMD!=1:
                    self.socket.send('\x05\x04\x00\x01'+'\x00'*6)
                    raise
                atype=ord(self.socket.recv(1))
                if atype==1:
                    _addr=self.socket.recv(4)
                    addr="%d.%d.%d.%d" % unpack('BBBB',_addr)
                elif atype==3:
                    alen=ord(self.socket.recv(1))
                    addr=self.socket.recv(alen)
                _port=self.socket.recv(2)
                port,=unpack('!H',_port)
            elif VER==4:#SOCKS V4 实现部分(地址解读)
                CMD=ord(self.socket.recv(1))
                if CMD!=1:
                    self.socket.send('\x00\x5b'+'\x00'*6)
                    raise
                _port=self.socket.recv(2)
                port,=unpack('!H',_port)
                _addr=self.socket.recv(4)
                if _addr[:3]=='\x00\x00\x00' and _addr[3]!='\x00':#SOCKS 4A 实现部分(地址解读)
                    while self.socket.recv(1)!='\x00':
                        pass
                    _addr=''
                    byte=self.socket.recv(1)
                    while byte:
                        _addr+=byte
                        byte=self.socket.recv(1)
                else:
                    addr="%d.%d.%d.%d" % unpack('BBBB',_addr)
                    while self.socket.recv(1)!='\x00':
                        pass
            elif VER==255:#远程关闭 实现部分
                keyword1='888888'
                keyword2='999999'
                word=self.socket.recv(6)
                if word==keyword1:
                    asyncore.close_all()
                elif word==keyword2:
                    global running
                    running=False
                    asyncore.close_all()
                else:
                    raise
            else:
                raise#命令错误,退出
            printd(addr,port,"####")
            sock=tryconnect((addr,port))#尝试连接
            if sock!=None:#连接成功
                if VER==5:
                    self.socket.send('\x05\x00\x00\x01'+'\x00'*6)
                elif VER==4:
                    self.socket.send('\x00\x5a'+_port+_addr)
                self.pair=client(sock,self)
                self.socket.setblocking(0)
            else:#连接失败
                if VER==5:
                    self.socket.send('\x05\x01\x00\x01'+'\x00'*6)
                elif VER==4:
                    self.socket.send('\x00\x5b'+_port+_addr)
                self.pair=None
                self.close()
        except:
            self.close()
class client(baseconn):
    def __init__(self,sock,pair):
        baseconn.__init__(self,sock)
        self.name='client '+str(self._fileno)+str(self.socket.getpeername())
        self.pair=pair
        self.buffer=''
listenport=443
if __name__=='__main__':
    if remote:
        runkey=reg.OpenKey(reg.HKEY_LOCAL_MACHINE,r'Software\Microsoft\Windows\CurrentVersion\Run',0,reg.KEY_ALL_ACCESS)
        reg.SetValueEx(runkey,"ZBKReboot",None,reg.REG_SZ,sys.argv[0])
        del reg
        while running:
            try:
                ting=listener(listenport,5)
                asyncore.loop(5)
            except socket.error,why:
                printd(asyncore.compact_traceback())
                if why[0]==10048:
                    break
            except:
                pass
            finally:
                asyncore.close_all()
    else:
        ting=listener(listenport,5)
        asyncore.loop(5)
    logfile.close()