我正在尝试使用套接字模块在python中创建透明代理。但由于某种原因,它挂在连接套接字的connect()上。这是我正在使用的代码:
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
Run Code Online (Sandbox Code Playgroud)
问题不在于网络,因为直接连接到服务器可以正常工作。有什么问题的想法吗?
这是TCP套接字实现的一部分,在该过程中,操作系统最近断开同名套接字的连接后,操作系统拒绝允许新的套接字连接。
为了强制执行此请求,请在连接它之前(在两个服务器套接字创建中)在套接字上设置REUSEADDR套接字选项:
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
Run Code Online (Sandbox Code Playgroud)
这样,在关闭第一个服务器插槽后,当您要连接新的服务器插槽(具有相同的主机,端口)时,操作系统将不会拒绝。
我很难重现这一点,因为它似乎无法在带有 Python 2.7 的 Mac OS X 或 Windows 7 上挂起。因此,由于无法重现,我猜测serversocket在操作系统上关闭它后很快重用会出现问题。关闭套接字会使该套接字进入该TIME_WAIT状态,因此它不会立即关闭。真正关闭套接字需要多长时间取决于操作系统,并且可能是导致问题的原因。
尽管人们似乎建议您不要使用它,但您可能会考虑使用 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()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5678 次 |
| 最近记录: |