Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python socket hangs on connect

Tags:

python

sockets

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?

like image 670
doxin Avatar asked Aug 27 '11 12:08

doxin


People also ask

What causes socket timeout?

TCP Socket Timeouts are caused when a TCP socket times out talking to the far end. Socket timeouts can occur when attempting to connect to a remote server, or during communication, especially long-lived ones.

What does socket timeout to Python?

Socket connection timeout High A new Python socket by default doesn't have a timeout. Its timeout defaults to None. Not setting the connection timeout parameter can result in blocking socket mode. In blocking mode, operations block until complete or the system returns an error.

What is socket Settimeout?

settimeout(value) and you set a float value greater than 0.0, that socket will raise a scocket. timeout when a call to, for example, socket. recv has to wait longer than the value specified.

How does Python handle connection timeout exception?

As for the problem with timeout, all you need to do is to change except socket. Timeouterror: to except timeout: , since timeout class is defined inside socket module and you have imported all its members to your namespace.


2 Answers

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.

like image 172
farzad Avatar answered Sep 29 '22 12:09

farzad


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()
like image 26
stderr Avatar answered Sep 29 '22 12:09

stderr