简体   繁体   中英

Python Simple TCP relay

I'm trying to build a simple TCP relay that accepts multiple client connection.

Client1 --> TCPrelay1 --> RealServer1 --> TCPrelay1 --> Client1
Client2 --> TCPrelay1 --> RealServer1 --> TCPrelay1 --> Client2
Client3 --> TCPrelay1 --> RealServer1 --> TCPrelay1 --> Client3

Something in that matter. No limit really on how many clients


I found a UDP relay script here .

I tried to modify it to TCP. I'm really new to python sockets. So what could be wrong with my code? Nothing is happening. And its not relaying.

#SOCK_STREAM --TCP
localPort = 5000
remotePort = 5000

#SV
remoteHost = "xxxxx"

try:
    localPort = int(localPort)
except:
    fail('Invalid port number: ' + str(localPort))
try:
    remotePort = int(remotePort)
except:
    fail('Invalid port number: ' + str(remotePort))

try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('', localPort))
    s.listen(1)
except:
    fail('Failed to bind on port ' + str(localPort))

knownClient = None

while True:
    conn, addr = s.accept()
    conn2, addr2 = s.connect((remoteHost, remotePort))
    data = connection.recv(1024)
    if knownClient is None:
        knownClient = addr
    if addr == knownClient:
        s.sendall(data)
        print "Sent     : " + ":".join("{0:X}".format(ord(c)) for c in data)
    else:   
        s.sendall(data)
        print "Received : " + ":".join("{0:X}".format(ord(c)) for c in data)

[disregard]
Did a few research and found this logic at another SO question:

import select

def fromAtoB(A, B):
    r, w = select.select([A], [B], [])
    if not r: select.select([A], [], [])
    elif not w: select.select([], [B], [])
    B.sendall(A.recv(4096))

But I'm still trying to understand how to implement it.

Your code accepts one connection and then relays one block of data on one direction and then never looks at that connection again.

Your second chunk of code has a variety of problems, but the big one is that it can deadlock. During your call to B.sendall , if B refuses to read any data until it is able to finish sending to A , which may be legal in the protocol you're relaying, your proxy and B will be waiting for each other forever because your proxy refuses to read any data from B until it finishes sending.

A proper relays must attempt to do four things at once and may not wait for one thing to finish before starting another. These four things are:

1) Read from connection A. (Unless a large amount of data is already backed up.)

2) Read from connection B. (Unless a large amount of data is already backed up.)

3) Write to connection A. (Unless there is no unrelayed data that has been received from connection B.)

4) Write to connection B. (unless there is no unrelayed data that has been received from connection A.)

In particular, you need two buffers, one for unsent data in each direction. You cannot alternate directions because that will require you to wait for one of the nodes to receive data, which can deadlock if that node is waiting for you to receive data.

Generally, the simplest way to implement a proxy is with two threads per connection, one for each direction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM