Подтвердить что ты не робот

Несколько одновременных сетевых подключений - сервер Telnet, Python

В настоящее время я пишу 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()

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

4b9b3361

Ответ 1

Реализовано в twisted:

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.

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

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

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

вокруг страницы 5/6 - пример, который очень важен;)

Ответ 7

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

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

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

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

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

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

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

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

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

Ответ 8

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

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

Ответ 9

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

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

 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()