I am trying to convert the following code written in python 2 to python 3. This python code does TCP port forwarding. It is from this page: http://code.activestate.com/recipes/483730-port-forwarding/
import socket
import sys
import thread
def main(setup, error):
sys.stderr = file(error, 'a')
for settings in parse(setup):
thread.start_new_thread(server, settings)
lock = thread.allocate_lock()
lock.acquire()
lock.acquire()
def parse(setup):
settings = list()
for line in file(setup):
parts = line.split()
settings.append((parts[0], int(parts[1]), int(parts[2])))
return settings
def server(*settings):
try:
dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
dock_socket.bind(('', settings[2]))
dock_socket.listen(5)
while True:
client_socket = dock_socket.accept()[0]
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.connect((settings[0], settings[1]))
thread.start_new_thread(forward, (client_socket, server_socket))
thread.start_new_thread(forward, (server_socket, client_socket))
finally:
thread.start_new_thread(server, settings)
def forward(source, destination):
string = ' '
while string:
string = source.recv(1024)
if string:
destination.sendall(string)
else:
source.shutdown(socket.SHUT_RD)
destination.shutdown(socket.SHUT_WR)
if __name__ == '__main__':
main('proxy.ini', 'error.log')
Here is what I have:
import socket
import sys
import threading
import time
def main(setup, error):
# open file for error messages
sys.stderr = open(error, 'a')
# read settings for port forwarding
threads = []
for settings in parse(setup):
#thread.start_new_thread(server, settings)
t = threading.Thread(target=server, args=(settings))
t.start()
threads.append(t)
for t in threads:
t.join()
# wait for <ctrl-c>
while True:
time.sleep(60)
def parse(setup):
settings = list()
file = open(setup)
for line in iter(file):
parts = line.split()
settings.append((int(parts[0]), parts[1], int(parts[2])))
return settings
def server(*settings):
try:
dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
dock_socket.bind(('', settings[0]))
dock_socket.listen(5)
while True:
client_socket = dock_socket.accept()[0]
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.connect((settings[1], settings[2]))
Thread1 = threading.Thread(target=forward, args=(client_socket, server_socket))
Thread1.start()
Thread2 = threading.Thread(target=forward, args=(server_socket, client_socket))
Thread2.start()
finally:
thread = threading.Thread(targer=server, args=settings)
thread.start()
def forward(source, destination):
string = ' '
while string:
string = source.recv(1024)
if string:
destination.sendall(string)
else:
source.shutdown(socket.SHUT_RD)
destination.shutdown(socket.SHUT_WR)
if __name__ == '__main__':
main('port-forward.config', 'error.log')
The python 3 version does seem to work. But I am not fully certain if it is written correctly. I am unclear about the threads portion of the code. The python 2 version is using the thread module while the python 3 version is using the threading module. Looking at the python 2 version, it uses locks in the main function. Do I need to use locks in the python 3 version? Another question is, should I be joining the two threads (thread 1 and thread 2) in the server function in the python 3 code?
Another question I have regardless of python version is the argument to the server function. I understand that the "settings" variable refers to a list. Why does there need to be a asterisk preceding the "settings" argument? I did take a look at the following page in python documentation https://docs.python.org/3/tutorial/controlflow.html#arbitrary-argument-lists
But I don't understand why passing the settings list without the asterisk doesn't work.
Another question I have is regarding the thread locks in the python 2 code. Why is the lock being acquired twice? I tried removing one of the locks and the program ends immediately after being started.