python套接字挂在连接上

时间:2011-08-27 12:29:46

标签: python sockets

我正在尝试使用套接字模块在python中创建透明代理。但由于某种原因,它挂在socket()上的socket。这是我正在使用的代码:

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

问题不在于网络,因为直接连接到服务器工作正常。关于出了什么问题的任何想法?

2 个答案:

答案 0 :(得分:5)

这是TCP套接字实现的一部分,其中操作系统在最近断开具有相同名称的套接字后拒绝允许新的套接字连接。

为了强制执行此请求,请在连接之前在套接字上设置REUSEADDR套接字选项(对于两个服务器套接字创建):

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

这样关闭第一个服务器套接字后,如果要连接新的服务器套接字(使用相同的主机,端口),OS就不会拒绝。

答案 1 :(得分:1)

我很难复制这个,因为它似乎没有挂在Mac OS X或Windows 7上使用Python 2.7。因此,无法重现我猜测在您的操作系统上关闭serversocket之后很快就会重新使用TIME_WAIT。关闭套接字会使该套接字进入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() 状态,因此它不会立即关闭。真正关闭套接字需要多长时间取决于操作系统,可能是导致问题的原因。

虽然人们似乎建议您不要使用它,但您可能会考虑使用SO_LINGER选项强制套接字立即关闭。

例如:

{{1}}