Программирование клиентского сервера в python?

Вот исходный код для многоуровневого сервера и клиента в python.

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

Следующий код: http://www.devshed.com/c/a/Python/Basic-Threading-in-Python/1/

import pickle
import socket
import threading

# We'll pickle a list of numbers:
someList = [ 1, 2, 7, 9, 0 ]
pickledList = pickle.dumps ( someList )

# Our thread class:
class ClientThread ( threading.Thread ):

   # Override Thread __init__ method to accept the parameters needed:
   def __init__ ( self, channel, details ):

      self.channel = channel
      self.details = details
      threading.Thread.__init__ ( self )

   def run ( self ):

      print 'Received connection:', self.details [ 0 ]
      self.channel.send ( pickledList )
      for x in xrange ( 10 ):
         print self.channel.recv ( 1024 )
      self.channel.close()
      print 'Closed connection:', self.details [ 0 ]

# Set up the server:
server = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
server.bind ( ( '', 2727 ) )
server.listen ( 5 )

# Have the server serve "forever":
while True:
   channel, details = server.accept()
   ClientThread ( channel, details ).start()

import pickle
import socket
import threading

# Here our thread:
class ConnectionThread ( threading.Thread ):

   def run ( self ):

      # Connect to the server:
      client = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
      client.connect ( ( 'localhost', 2727 ) )

      # Retrieve and unpickle the list object:
      print pickle.loads ( client.recv ( 1024 ) )

      # Send some messages:
      for x in xrange ( 10 ):
         client.send ( 'Hey. ' + str ( x ) + '\n' )

      # Close the connection
      client.close()

# Let spawn a few threads:
for x in xrange ( 5 ):
   ConnectionThread().start()

Ответ 1

Появление нового потока для каждого подключения - это дизайн очень плохой. Что произойдет, если вас поразит множество подключений?

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

Следующий текст из документации python:

Есть только два способа иметь программа на одном процессоре делает "больше чем одна вещь одновременно". Многопоточное программирование Простейший и самый популярный способ сделать это, но есть еще одна очень другой метод, который позволяет вам имеют почти все преимущества многопоточность, без используя несколько потоков. Это правда только если ваша программа в значительной степени связан с В/В. Если ваша программа процессор, а затем упреждающий запланированные потоки, вероятно, вам действительно нужно. Сетевые серверы реже обрабатывается процессор.

И если это процессор, связанный с сервером. вы всегда можете оставить другой процесс/поток для обработки части процессора. Продолжение:

Если ваша операционная система поддерживает выберите системный вызов в своей библиотеке ввода-вывода (и почти все делают), то вы можете использовать он жонглирует несколькими сообщениями каналы одновременно; делать другую работу в то время как ваш ввод-вывод выполняется в "задний план." Хотя эта стратегия может показаться странным и сложным, особенно во-первых, это во многих способы легче понять и контролировать чем многопоточное программирование.

Поэтому вместо использования потоков используйте неблокирующий ввод/вывод: собирайте сокеты в списке и используйте цикл событий с select.select знать, какой сокет имеет данные для чтения. Сделайте это в одном потоке.

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

EDIT. Любые существующие асинхронные IO-библиотеки (например, Twisted) представляют собой код Python. Вы могли написать это сами, но это уже написано для вас. Я не понимаю, почему вы не будете использовать одну из этих библиотек и вместо этого напишите свой собственный худший код, так как вы новичок. Networing IO трудно понять.

Ответ 2

Я не уверен, что понимаю этот вопрос, но не вызываю close(), если вы не хотите закрыть соединение...

Ответ 3

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

Пример сервера, который поддерживает открытие TCP-соединения, находится в источнике для SocketServer module (любая стандартная установка Python включает источник).