Сетевой клиент Python, пытающийся отвечать на ответы сервера - PullRequest
1 голос
/ 18 апреля 2011

Приложение представляет собой клиент-серверную установку WxPython, в которой несколько клиентов подключаются к серверу и используют дуплексный сетевой протокол.

В прошлом я уже подключал Twisted к AMP, но он не полностью соответствовал архитектуре приложения без чрезмерного усложнения в итоге.

Итак, для сервера у меня установлен SocketServer с настроенным ThreadingMixIn. В данный момент я работаю над буфером / очередью команд для сервера, но это не проблема.

На стороне клиента я могу выполнять все обычные операции по отправке данных, инициируемые событиями в пользовательском интерфейсе, без особых проблем. В настоящее время я застрял, пытаясь заставить клиента прослушивать ответы, не блокируя все приложение. Поэтому я хочу поместить это в поток, но должно ли оно начаться с той части, которая сейчас закомментирована, или это должно быть обработано совершенно по-другому, и я просто не вижу этого?

Вкратце: я хочу, чтобы клиент отправлял команды на сервер и прослушивал любые ответы, не блокируя / не останавливая все приложение.

Приведенный ниже код является прототипом кода, прошу прощения за любые типичные ошибки, такие как магические значения и другие жестко закодированные данные, в конечном коде они будут другими.

import socket
import threading
import time


class CommandProxy(object):
    def __init__(self, host, port):
        self.host = host
        self.port = port

    def close(self):
        if self.connection:
            self.connection.close()

    def connect(self):
        try:
            self.connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.connection.connect((self.host, self.port))
        except socket.error as e:
            print "Socket error: {0}".format(e)

    def send_command(self, command, *kw):
        datalist = ' '.join(kw)
        data = command + ' ' + datalist + '\x00'

        print 'DATA: {0}'.format(data)

        self._write(data)

#        while True:
#            data = self._read()
#            if data == 0:
#                break
#
#        print "DATA RECEIVED: {0}".format(data)

    def _read(self):
        data = self.connection.recv(1024)
        return data

    def _write(self, bytes):
        self.connection.sendall(bytes)


if __name__ == '__main__':
    HOST, PORT = 'localhost', 1060

    proxy = CommandProxy(HOST, PORT)
    proxy.connect()
    try:
        while True:
            proxy.send_command('ID', '1')
            time.sleep(2)

    except KeyboardInterrupt:
        print "Interrupted by user"
    except socket.error as e:
        print "Socket error: {0}".format(e)
    except Exception as e:
        print "something went wrong: {0}".format(e)
    finally:
        proxy.close()

Ответы [ 2 ]

1 голос
/ 18 апреля 2011

Я думаю, вы ошибаетесь в том, будет ли однопоточный или многопоточный подход более или менее усложнять ваше приложение. Проблема, с которой вы сейчас боретесь, одна из многих, которые (например) Twisted решает для вас из коробки.

Самая распространенная жалоба людей на Twisted - это то, что они странным образом структурируют свой код, к чему они не привыкли. Однако, когда вы используете библиотеку GUI, такую ​​как wxPython, вы уже приняли это ограничение. Управляемая событиями архитектура Twisted в точности похожа на управляемую событиями архитектуру всех популярных инструментов GUI. Пока вы продолжаете использовать wxPython, использование Twisted также не заставит вас делать что-либо иначе , которое вы не хотите делать.

С другой стороны, переключение на потоки означает, что вы должны быть очень осторожны с доступом к общим структурам данных, вы не сможете эффективно выполнять модульное тестирование, и многие возникающие проблемы будут выполняться только тогда, когда кто-то другой запуск вашего приложения - потому что у них другое количество ядер, чем у вас, или их сеть имеет другие характеристики задержки, или любые другие факторы, которые заставляют ваш многопоточный код работать так, как вы никогда не испытывали. С особой тщательностью вы все еще можете написать что-то, что работает, но это будет намного сложнее.

Поскольку вы не разместили здесь свой код на основе Twisted, я не могу дать какой-либо конкретный совет о том, как сделать вещи максимально простыми. Тем не менее, я рекомендую вам еще раз взглянуть на непотоковое решение. Присоединитесь к списку рассылки twisted-python@twistedmatrix.com, перейдите на #twisted на freenode или опубликуйте дополнительные вопросы об этом через stackoverflow. Многие люди будут рады помочь. :)

0 голосов
/ 18 апреля 2011

IMO ваше право с использованием потока.Запускайте поток для каждого запроса, а когда он будет выполнен и у вас есть данные, создайте событие wx (см. http://wiki.wxpython.org/CustomEventClasses)

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