Сообщения сокетов отправляются быстрее, чем приложение может получить - PullRequest
0 голосов
/ 09 февраля 2020

Я довольно новичок в программировании сокетов и не уверен насчет конкретного сценария c:

Допустим, у меня есть приложение (python), у которого открыт сервер сокетов и который прослушивает TCP 127.0 .0.1 порт 2030.

С помощью poll_interval это приложение может получать и обрабатывать 20 сообщений в секунду. Но третья сторона (которую я не могу контролировать) отправляет 40 сообщений в секунду.

Я заметил, что через некоторое время сервер сокетов приложений зависает и не может получить никакого нового соединения.

Я проверил состояние сокета на моей машине:

ss -pl | grep 2030

И видите, что в Recv-Q есть сотни носков, которые не уходят.

root@mymachine:~# ss -l | grep 2030
tcp    LISTEN     578      5            127.0.0.1:2030                  *:*

Кроме того, я заметил сотни сокетов в состоянии close-wait :

root@mymachine:~# netstat -ton | grep CLOSE_WAIT | grep 2030
tcp      580      0 127.0.0.1:2030          127.0.0.1:34200         CLOSE_WAIT  off (0.00/0/0)

Это связано? И если да, то как защитить приложение сокета от пропускной способности, превышающей ожидаемую? / сек. Это по замыслу. Вопрос в том, как защитить приложения сокетов от пропускной способности, для которой они не предназначены.

В любом случае, я делюсь некоторым кодом:

socketserver.TCPServer.allow_reuse_address = True
server = socketserver.TCPServer((HOST, PORT), SocketHandler)

threading.Thread(target=server.serve_forever, kwargs={'poll_interval': 0.002}).start()

class SocketHandler(socketserver.BaseRequestHandler):

def handle(self):

    data = self.request.recv(1500)

    try:
        decoded = data.decode("utf-8")
        parsed = do_some_parsing()

        if not parsed:
            raise UnreadableMessage("Couldn't parse {}".format(data))

    except UnreadableMessage as e:
        logger.warning(e)

    except Exception as e:
        logger.error("Unknown exception occurred when tried to parse message: {]".format(data))

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