Simple network agent -- writen by python

2015/08/3023:38:51Simple network agent -- writen by python已关闭评论

1、从语言的选择方向来说,因为我目的是要方便生活使用,希望能快速达到目的,如果用C和C++来说,工作量稍大些,于是选择了我还算熟悉的python语言

2、里面比较有意思的是在于数据的转发,代理既要承担“送出去”的任务,也要承担“送回来”的任务,思考了下数据结构的使用,使用了字典的方式,即client->forward,forward->client,如果用C来实现的话,就是封装一个结构体,里边有客户端连接的socket,也有传送回来的forward sokcet

3、一旦接收到有客户端连接代理程序,代理程序马上向要转发的目的机器进行TCP连接的建立,同时将双方的socket信息成对保存在字典中

4、采用简单的select模型,主要是图个便利,当有活动的socket连接时,能马上检测到socket句柄的活动,从而从字典中找到对应的socket连接信息

总结:既然选择了写程序,碰到看不顺手,或操作麻烦的事情,就来个程序终结它,Orz!

技术没有所谓最好的语言,语言只是工具,但要用好,别伤了自己,在合理的事情上选择对的工具,让那些争论PHP是最好的语言的人浪费时间去吧。最后:上程序!!叮叮叮!

#coding=utf-8
import socket
import select
import sys
import threading
import time
import logging
import os
logsDir = "logs"
#目录不存在则创建
if not os.path.isdir(logsDir):
    os.mkdir(logsDir)
#记录日志
logging.basicConfig(level=logging.DEBUG,
                format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                datefmt='%a, %d %b %Y %H:%M:%S',
                filename='logs/logs.log',
                filemode='a')

#C的IP和端口
to_addr = ()

#最大连接数
maxConnetions = 32
class Proxy:
    def __init__(self, addr):
        self.proxy = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.proxy.bind(addr)
        self.proxy.listen(maxConnetions)
        self.inputs = {self.proxy:None}
        self.route = {}

    def serve_forever(self):
        logging.info('proxy listen...')
        while 1:
            readable, _, _ = select.select(list(self.inputs.keys()), [], [])
            for self.sock in readable:
                if self.sock == self.proxy:
                    self.on_join()
                else:
                    try:
                        data = self.sock.recv(8192)
                    except Exception, e:
                        logging.error(str(e))
                        self.on_quit()
                        continue

                    if not data:
                        self.on_quit()
                    else:
                        try:
                            self.route[self.sock].send(data)
                        except Exception, e:
                            logging.error(str(e))
                            self.on_quit()
                            continue

    def on_join(self):
        client, addr = self.proxy.accept()
        logging.info("proxy client " + str(addr) + 'connect')
        forward = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            forward.connect(to_addr)
        except Exception, e:
            logging.error(str(e))
            client.close()
            return
        self.inputs [client] = None
        self.inputs [forward] = None

        self.route[client] = forward
        self.route[forward] = client

    #删除连接
    def on_quit(self):
        ls = [self.sock]
        if self.sock in self.route:
            ls.append(self.route[self.sock])
        for s in ls:
            if s in self.inputs:
                del self.inputs展开
            if s in self.route:
                del self.route展开
            s.close()

if __name__ == '__main__':
    proxy = Proxy(('',54321))
    try:
        
        with open('proxy.conf',"r") as fd:
            info_list = fd.readline().split(',')
            to_addr = (info_list[0],int(info_list[1]))
            print to_addr
        
        proxy.serve_forever()#代理服务器监听的地址
    except KeyboardInterrupt:
        sys.exit(1)

最后,我用pyinstaller生成了一个可执行的二进制程序,使用说明都在里边了

简单的网络代理工具(附使用说明和python源码)

  • 微信扫码赞助
  • weinxin
  • 支付宝赞助
  • weinxin