2011-08-27 5 views
3

J'essaie de créer un proxy transparent en python en utilisant le module socket. mais pour une raison quelconque, il se bloque sur connect() ing la socket. voici le code que j'utilise:Le socket python se bloque lors de la connexion

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 

le problème ne réside pas dans le réseau car la connexion au serveur fonctionne directement. des idées sur ce qui ne va pas?

Répondre

1

J'ai du mal à reproduire cela car il ne semble pas se bloquer sur Mac OS X ou Windows 7 avec Python 2.7. Donc, sans être en mesure de reproduire je suppose qu'il y a un problème avec la réutilisation serversocket si peu après la fermeture sur votre système d'exploitation. La fermeture d'une socket place cette socket dans l'état TIME_WAIT afin qu'elle ne soit pas fermée immédiatement. Le temps nécessaire pour vraiment fermer le socket dépend du système d'exploitation et peut être à l'origine de votre problème.

Bien que les utilisateurs semblent vous recommander de ne pas l'utiliser, vous pouvez envisager d'utiliser l'option SO_LINGER pour forcer la fermeture immédiate du socket.

Par exemple:

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() 
3

Ceci est une partie des sockets TCP où la mise en œuvre du système d'exploitation refuse de permettre une nouvelle connexion prise après une prise du même nom a été déconnecté récemment.

Pour forcer cette demande, définissez l'option de prise REUSEADDR sur votre prise, avant de le connecter (pour les deux de vos créations socket serveur):

serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 

De cette façon après votre fermer votre première prise de serveur, Lorsque vous souhaitez connecter votre nouveau socket serveur (avec le même hôte, port), OS ne refusera pas.

+2

Ceci s'applique à 'bind()'. L'auteur dit qu'il se fige sur 'connect()'. Cela signifie probablement que 'connect()' est suspendu en train de résoudre l'adresse IP ou que le serveur ne répond pas avec 'SYN + ACK'. –

+0

qui devrait donner une adresse déjà utilisée exception exception. – doxin

Questions connexes