Reputation: 718
I'm trying to make a transparent proxy in python using the socket module. but for some reason it hangs on connect()ing the socket. here is the code i'm using:
from __future__ import division
import socket
import struct
#import mcpackets
import sys
import time
#CUSTOM SETTINGS
HOST="192.168.178.28"
PORT=25565
#END CUSTOM SETTINGS
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('',25565))
serversocket.listen(1)
print "waiting for client, press multiplayer and use 'localhost' as server"
clientsocket,address=serversocket.accept()
print "client connected from %s:%d"%address
serversocket.close()
print "connecting to '%s:%d'"%(HOST,PORT)
serversocket=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "socket created."
serversocket.connect((HOST,PORT))#------------------------------ freezes here
print "socket connected."
serversocket.settimeout(0)
clientsocket.settimeout(0)
print "timeouts set."
print "now proxying."
#tdata=[]
try:
while(True):
dat=None
try:
dat=clientsocket.recv(4096)
except socket.timeout:
pass
if(dat!=None):
try:
serversocket.send(dat)
except socket.timeout:
pass
#vice versa
dat=None
try:
dat=serversocket.recv(4096)
except socket.timeout:
pass
if(dat!=None):
try:
clientsocket.send(dat)
except socket.timeout:
pass
except:
clientsocket.close()
#with open("data.log","w") as fid:
# fid.write(''.join(tdata))
raise
the problem doesn't lie in the network as connecting to the server directly works fine. any ideas on what's going wrong?
Upvotes: 7
Views: 13197
Reputation: 8855
This is a part of TCP sockets implementation where the operating system refuses to allow a new socket connection after a socket with the same name has been disconnected recently.
In order to force this request, set the REUSEADDR socket option on your socket, before connecting it (for both of your server socket creations):
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
This way after you close your first server socket, when you want to connect the new server socket (with the same host, port), OS would not refuse.
Upvotes: 6
Reputation: 8732
I'm having difficulty reproducing this as it doesn't appear to hang on Mac OS X or Windows 7 with Python 2.7. So without being able to reproduce I'm guessing there's a problem with reusing serversocket
so soon after closing it on your OS. Closing a socket puts that socket into the TIME_WAIT
state so it's not closed immediately. How long it takes to really close the socket is dependent on the OS and may be what's causing your problem.
Although people seem to recommend that you don't use it, you might look into using the SO_LINGER option to force the socket to close immediately.
For example:
l_onoff, l_linger = 1, 1 # send RST (hard reset the socket) after 1 second
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
struct.pack('ii', l_onoff, l_linger))
# this should now complete after l_linger timeout
serversocket.close()
Upvotes: 1