2011-08-27 7 views
3

나는 소켓 모듈을 사용하여 파이썬에서 투명한 프록시를 만들려고합니다. 하지만 어떤 이유로 소켓에 connect()를 걸면 멈 춥니 다.python 소켓 연결이 끊어졌습니다

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 

문제가 직접적으로 잘 작동 서버에 연결로 네트워크에 거짓말을하지 않습니다 여기 내가 사용하고 코드입니다. 무슨 일이 일어나고 있는지에 대한 아이디어가 있습니까?

답변

1

Mac OS X 또는 Windows 7 (Python 2.7)에서 멈추는 것처럼 보이지 않으므로 재현하는 데 어려움이 있습니다. 재현 할 수 없으면 OS에서 닫은 후 serversocket을 다시 사용하는 데 문제가 있다는 것을 짐작할 수 있습니다. 소켓을 닫으면 해당 소켓이 TIME_WAIT 상태로 바뀌므로 즉시 닫히지 않습니다. 소켓을 실제로 닫는 데 걸리는 시간은 OS에 따라 다르며 문제의 원인이 될 수 있습니다.

사람들이 사용하지 않는 것이 좋지만 SO_LINGER 옵션을 사용하면 소켓을 즉시 닫아야합니다. 예를 들어

:

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

이 최근 분리 된 운영 체제가 같은 이름을 가진 소켓 후 새로운 소켓 연결을 허용하도록 거부 TCP 소켓 구현의 일부입니다. (서버 소켓 작품의 모두),이 요청을 강제로 연결하기 전에, 당신의 소켓의 REUSEADDR 소켓 옵션을 설정하기 위해

:

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

이 방법은 첫 번째 서버 소켓 친한 후, 새로운 서버 소켓 (동일한 호스트, 포트)을 연결하려고 할 때 OS는 거부하지 않을 것입니다.

+2

이는'bind()'에 적용됩니다. 저자는'connect()'에서 멈추는다고 말한다. 이것은 아마도'connect()'가 IP 주소를 결정하는 걸 멈추고 있거나 서버가'SYN + ACK '로 응답하지 않는다는 것을 의미합니다. –

+0

은 이미 사용중인 주소에 예외를 제공해야합니다. – doxin

관련 문제