我用python写一个服务器,它可以工作。它可以向客户端发送数据或从客户端接收数据。每当我更改此代码语法并想要执行它时,我都会更改端口号(将1加上前一个数字)。更改端口号4到5次后,客户端无法连接到服务器,并且会收到TCP连接超时错误,尽管该端口可从服务器使用。我使用大力神作为客户。问题实际上并不取决于我更改端口号的时间。如果服务器等待或用一点时间来监听(我不知道那是多少时间),我也有同样的问题,即使更改端口号,客户端也无法连接到服务器。而客户端显示TCP连接超时错误服务器在终端中显示此错误:
urllib3.connectionpool - DEBUG - https://api.mycroft.ai:443 "GET
/v1/device/0bcdba9f-4a90-4fdf-977a-61eb54afea9c/skill HTTP/1.1" 304 0
这是我使用的服务器代码:
class server(object):
def __init__(self, host, port):
self.host = get_ip.get_ip_address('wlan0') #'192.168.1.102'
self.port = 1924
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind((self.host, self.port))
def listen(self,after_idle_sec, interval_sec, max_fails):
m = self.sock.getsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE)
if(m ==0):
print("SOCKET KEEPALIVE OFF, TURNING ON")
self.set_keepalive_osx(after_idle_sec, interval_sec, max_fails)
print("interval_sec:", interval_sec)
print("after_idle_sec:", after_idle_sec)
print("max_fails:", max_fails)
else:
print("SOCKET KEEPALIVE IS ALREADY ON")
self.sock.listen(5)
print('WAITING FOR A CONNECTION')
while True:
client, address = self.sock.accept()
#client.settimeout(60)
Thread(target = self.client_thread, args = (client,address)).start()
def set_keepalive_osx(self, after_idle_sec=1, interval_sec=3, max_fails=5):
"""Set TCP keepalive on an open socket.
sends a keepalive ping once every 3 seconds (interval_sec)
"""
# scraped from /usr/include, not exported by python's socket module
TCP_KEEPALIVE = 0x10
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, after_idle_sec)
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, interval_sec)
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, max_fails)
def shutdown(self): #terminate server
self.sock.shutdown(socket.SHUT_RDWR) #further sends and receives are disallowed
self.sock.close()
print ("closed")
def client_thread(自己,客户,地址):
while True:
size = 1024
try:
self.servermsg = client.recv(size)
print("data received from client is: {}".format(self.servermsg))
if self.servermsg:
# Set the response to echo back the recieved data
response = self.servermsg
#do something
else:
#raise error('Client disconnected')
raise Exception('Client disconnected')
except Exception as e:
print(repr(e))
client.close()
return False
这不完全是我的代码,我删除了一些方法。
我认为它可能与setttimeout(60)
有关,但是在我发表评论后,我遇到了同样的问题。我应该重新启动系统,每次重新启动后我都会遇到此问题。添加“ set_keepalive_osx”方法后,出现此错误:
in set_keepalive_osx
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, after_idle_sec)
AttributeError: module 'socket' has no attribute 'TCP_KEEPIDLE'
我更改listen
方法并在其中调用'set_keepalive_osx'方法。之后,我没有上面的错误,但我不知道它是否起作用。如果我几分钟不使用它,它不会发送超时错误,并且当客户端断开连接时也会出现此错误:
ConnectionResetError(104, 'Connection reset by peer')
而不是引发一个client disconnected
异常。有人可以告诉我问题出在哪里吗?