doxin
doxin

Reputation: 718

python socket hangs on connect

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

Answers (2)

farzad
farzad

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

stderr
stderr

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

Related Questions