Python socketserver иногда прекращает отправлять (и получать?) сообщения - PullRequest
1 голос
/ 09 января 2012

У меня возникла проблема с сокет-сервером, который я написал, когда сокет-сервер, по-видимому, прекращает отправку и получение данных на одном из используемых им портов (в то время как другой порт продолжает обрабатывать данные очень хорошо).Интересно, что после ожидания в течение минуты (или до часа или около того), сервер-сокет начнет отправлять и получать сообщения снова без какого-либо видимого вмешательства.

Я использую инфраструктуру сокетов Eventlet, python 2.7, все работаетЭкземпляр Ubuntu AWS с внешними приложениями, открывающими постоянные соединения с сокет-сервером.

Из некоторых моих чтений похоже, что я не правильно внедряю свой сокет-сервер.Согласно http://docs.python.org/howto/sockets.html:

фундаментальная истина о сокетах: сообщения должны быть либо фиксированной длины (фу), либо разделяться>> (пожать плечами), либо указывать, насколько они длинны (намного лучше), илиВ завершение отключите соединение.

Я не совсем уверен, что я использую здесь сообщение фиксированной длины (или я?)

Так я получаю свои данные:

def socket_handler(sock, socket_type):
    logg(1,"socket_handler:initializing")
    while True:
        recv = sock.recv(1024)
        if not recv:
            logg(1,"didn't recieve anything")
            break
        if len(recv) > 5:
            logg(1,"socket handler: %s" % recv )
            plug_id, phone_sid, recv_json = parse_json(recv)
            send = 1 
            if "success" in recv_json and recv_json["success"] == "true" and socket_type == "plug":
                send = 0
            if send == 1:
                send_wrapper(sock, message_relayer(recv, socket_type))
        else:
            logg(2, 'socket_handler:Ignoring received input: ' + str(recv)  )
    logg(1,  'Closing socket handle: [%s]' % str(sock))
    sock.shutdown(socket.SHUT_RDWR)
    sock.close()

«sock» - это объект сокета, возвращаемый функцией listener.accept ().

Функция socket_handler вызывается так:

new_connection, address = listener.accept()
...<code omitted>...
pool.spawn_n(socket_handler, new_connection, socket_type)

Моя реализация выглядит неправильно для кого-либо?Я в основном реализую протокол беседы фиксированной длины?Что я могу сделать, чтобы помочь исследовать проблему или сделать мой код более надежным?

Заранее спасибо,

T

1 Ответ

2 голосов
/ 09 января 2012

Возможно, у вас возникли проблемы с буферизацией, если вы запрашиваете на сервере больше байтов (1024), чем фактически отправляете с клиента.

Чтобы решить проблему, обычно сначала кодируют длину сообщения, а затем само сообщение. Таким образом, получатель может получить поле длины (которое имеет известный размер) и затем прочитать остальную часть сообщения на основе декодированной длины.

Примечание. Поле длины обычно занимает столько байтов, сколько вам нужно в протоколе. Некоторые протоколы выровнены по 4 байта и используют для этого 32-битное поле, но если вы обнаружите, что вам достаточно 1 или 2 байта, вы можете использовать это. Дело в том, что и клиент, и сервер знают размер этого поля.

...