废话不说,贴代码. 这个版本使用select, 没有使用多线程. 使用多线程的还要简单一点.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#   datapipe.py
#   Copyright (C) 2007 Filia Tao
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License along
#   with this program; if not, write to the Free Software Foundation, Inc.,
#   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import sys
import socket
import SocketServer
from select import select
import traceback
sample_config = {
    "server_addr":("",2323),
    "remote_addr":("58.192.114.8",23)
}
 
class datapipeServer(SocketServer.TCPServer):
    def __init__(self,config):
        SocketServer.TCPServer.__init__(self,config["server_addr"],None)
        self.config = config
        self.in_sockets = []
        self.out_sockets = []
        self.pair = {}
 
    def serve_forever(self):
        print self.config
        while True:
            try:
                tri = select([self.socket] + self.in_sockets + self.out_sockets,[],[])
                for s in tri[]:
                    if s is self.socket:
                        ins,client_addr = self.get_request()
                        print "handle client " + str(client_addr)
                        outs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                        outs.bind((self.config["server_addr"][],))
                        outs.connect(self.config["remote_addr"])
                        self.pair[ins] = outs
                        self.pair[outs] = ins
                        self.in_sockets.append(ins)
                        self.out_sockets.append(outs)
                    elif s in self.in_sockets:
                        data = s.recv(4096)
                        if(self.pair[s].send(data)<=):
                            print "client " + str(s.getpeername()) + " disconnected";
                            self.pair[s].close()
                            s.close()
                            self.in_sockets.remove(s)
                            self.out_sockets.remove(self.pair[s])
 
                    elif s in self.out_sockets:
                        data = s.recv(4096)
                        if(self.pair[s].send(data)<=):
                            print "client " + str(self.pair[s].getpeername()) + " disconnected";
                            self.pair[s].close()
                            s.close()
                            self.out_sockets.remove(s)
                            self.in_sockets.remove(self.pair[s])
 
            except Exception,e:
                print "Error Occous"
                #traceback.print_stack()
                print e
 
def run(server_class=datapipeServer,
        config=sample_config):
    print "start server on " + str(config["server_addr"])
    datapiped = server_class(config)
    datapiped.serve_forever()
 
def print_help():
    print '''datapipe.py  A datapipe program (by python@bbs.seu.edu.cn)
usage: python datapipe.py [localhost] localport remotehost remoteport
examples:  python datapipe.py 23 bbs.seu.edu.cn 23
           python datapipe.py 10.22.0.2 2323 58.192.114.8 23
'''
if __name__ == "__main__":
    if len(sys.argv) < 4:
        print_help()
        sys.exit()
    elif len(sys.argv) == 4:
        argv = [""] + sys.argv[1:]
    else:
        argv = sys.argv[1:]
    #print argv
    myconfig = {
        "server_addr":(argv[],int(argv[1])),
        "remote_addr":(argv[2],int(argv[3])),
    }
    run(config = myconfig)