Несколько одновременных сетевых подключений - сервер Telnet, Python - PullRequest
16 голосов
/ 22 апреля 2009

В настоящее время я пишу сервер Telnet на Python. Это контент-сервер. Люди будут подключаться к серверу через telnet и получать только текстовый контент.

Моя проблема заключается в том, что сервер, очевидно, должен поддерживать более одного одновременного соединения. Текущая реализация у меня сейчас поддерживает только одну.

Это базовый сервер для проверки концепции, с которого я начал (хотя программа со временем сильно изменилась, а базовая среда telnet - нет):

import socket, os

class Server:
    def __init__(self):
        self.host, self.port = 'localhost', 50000
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.bind((self.host, self.port))

    def send(self, msg):
        if type(msg) == str: self.conn.send(msg + end)
        elif type(msg) == list or tuple: self.conn.send('\n'.join(msg) + end)

    def recv(self):
        self.conn.recv(4096).strip()

    def exit(self):
        self.send('Disconnecting you...'); self.conn.close(); self.run()
        # closing a connection, opening a new one

    # main runtime
    def run(self):
        self.socket.listen(1)
        self.conn, self.addr = self.socket.accept()
        # there would be more activity here
        # i.e.: sending things to the connection we just made


S = Server()
S.run()

Спасибо за вашу помощь.

Ответы [ 9 ]

16 голосов
/ 22 апреля 2009

Реализовано в витой :

from twisted.internet.protocol import Factory, Protocol
from twisted.internet import reactor

class SendContent(Protocol):
    def connectionMade(self):
        self.transport.write(self.factory.text)
        self.transport.loseConnection()

class SendContentFactory(Factory):
    protocol = SendContent
    def __init__(self, text=None):
        if text is None:
            text = """Hello, how are you my friend? Feeling fine? Good!"""
        self.text = text

reactor.listenTCP(50000, SendContentFactory())
reactor.run()

Тестирование:

$ telnet localhost 50000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello, how are you my friend? Feeling fine? Good!
Connection closed by foreign host.

Серьезно, когда дело доходит до асинхронной сети, витой путь. Он обрабатывает несколько соединений в однопоточном однопроцессном подходе.

4 голосов
/ 07 марта 2010

Поздно для ответа, но единственными ответами были Twisted или темы (ой), я хотел добавить ответ для MiniBoa.

http://code.google.com/p/miniboa/

Twisted - это здорово, но это довольно большой зверь, который может быть не лучшим введением в однопоточное асинхронное программирование Telnet. MiniBoa - это легкая асинхронная однопотоковая реализация Python Telnet, изначально разработанная для рабочих процессов, которая идеально подходит для вопроса OP.

4 голосов
/ 22 апреля 2009

Вам нужна некоторая форма асинхронного ввода-вывода сокета. Взгляните на это объяснение , которое обсуждает концепцию в терминах сокетов низкого уровня, и соответствующие примеры, которые реализованы в Python. Это должно указать вам правильное направление.

3 голосов
/ 22 апреля 2009

Для действительно легкого выигрыша внедрите ваше решение, используя SocketServer и SocketServer.ThreadingMixIn

посмотрите на этот пример эхо-сервера, он выглядит очень похоже на то, что вы делаете в любом случае: http://www.oreillynet.com/onlamp/blog/2007/12/pymotw_socketserver.html

2 голосов
/ 22 апреля 2009

Если вы готовы принять концептуальную задачу, я бы попробовал использовать витую.

Ваш кейс должен быть тривиальным для реализации как часть витой. http://twistedmatrix.com/projects/core/documentation/howto/servers.html

1 голос
/ 11 августа 2013

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

Посмотрите на это

 import socket               # Import socket module
import pygame
import thread
import threading,sys

s = socket.socket()         # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345                # Reserve a port for your service.
s.bind((host, port))
print ((host, port))
name = ""
users = []

def connection_handler (c, addr):
      print "conn handle"
      a = c.recv (1024)
      if a == "c":
         b = c.recv (1024)
      if a == "o":
         c.send (str(users))
         a = c.recv (1024)
         if a == "c":
            b = c.recv (1024)
      print a,b






s.listen(6)                 # Now wait for client connection.
while True:
   c, addr = s.accept()
   print 'Connect atempt from:', addr[0]
   username = c.recv(1024)
   print "2"
   if username == "END_SERVER_RUBBISH101":
      if addr[0] == "192.168.1.68":
         break
   users.append(username)
   thread.start_new_thread (connection_handler, (c, addr)) #New thread for connection

print 
s.close()
1 голос
/ 08 мая 2011

Попробуйте сервер MiniBoa? У него ровно 0 зависимостей, никаких скрученных или других необходимых вещей. MiniBoa - это неблокирующий асинхронный сервер Telnet, однопоточный, именно то, что вам нужно.

http://code.google.com/p/miniboa/

1 голос
/ 22 апреля 2009

Сначала купите книги Comer по Программирование TCP / IP .

В этих книгах Comer предоставит несколько альтернативных алгоритмов для серверов. Существует два стандартных подхода.

  • Thread-за запрос.

  • Процесс-за запрос.

Вы должны выбрать один из этих двух и реализовать это.

В thread-per каждый сеанс telnet является отдельным потоком в вашем общем приложении.

В process-per каждый сеанс telnet разбивается на отдельный подпроцесс.

Вы обнаружите, что процесс на запрос намного проще в Python и, как правило, обеспечивает более эффективное использование вашей системы.

Thread-per-request подходит для вещей, которые приходят и уходят быстро (например, HTTP-запросы). В Telnet есть длительные сеансы, в которых стоимость запуска подпроцесса не влияет на производительность.

1 голос
/ 22 апреля 2009

Если вы хотите сделать это в чистом Python (без перекручивания), вам нужно выполнить несколько потоков. Если вы не видели это раньше, проверьте: http://heather.cs.ucdavis.edu/~matloff/Python/PyThreads.pdf

на странице 5/6 является примером, очень соответствующим;)

...