商务合作加Q:411239339

Simple network agent — writen by python

浏览:362次阅读
没有评论

共计 3310 个字符,预计需要花费 9 分钟才能阅读完成。

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[s]
            if s in self.route:
                del self.route[s]
            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 源码)

正文完
扫码赞助
post-qrcode
 0
果子
版权声明:本站原创文章,由 果子 于2015-08-30发表,共计3310字。
转载说明:除特殊说明外本站文章皆由果较瘦原创发布,转载请注明出处。