клиент не может подключиться к серверу после некоторых подключений (python) - PullRequest
0 голосов
/ 05 ноября 2018

Я пишу сервер на 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. Может ли кто-нибудь высказать мне, в чем проблема?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...