Я пишу сервер на Python, и он работает. он может отправлять и получать данные от клиента. каждый раз, когда я изменяю этот синтаксис кода и хочу его выполнить, я меняю номер порта (добавьте 1 к предыдущему номеру). и после 4 или пятикратного изменения номера порта клиент не может подключиться к серверу, и он получает ошибку тайм-аута соединения 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 (self, client, address):
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
. Может ли кто-нибудь высказать мне, в чем проблема?