16

我目前正在用 Python 编写一个 telnet 服务器。它是一个内容服务器。人们将通过 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()

谢谢你的帮助。

4

9 回答 9

16

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.

说真的,当涉及到异步网络时,twisted 是要走的路。它以单线程单进程方法处理多个连接。

于 2009-04-22T11:54:36.097 回答
4

您需要某种形式的异步套接字 IO。看看这个解释,它讨论了低级套接字术语的概念,以及用 Python 实现的相关示例。那应该为您指明正确的方向。

于 2009-04-22T08:16:13.940 回答
4

回复晚了,但唯一的答案是 Twisted 或线程(哎哟),我想为 MiniBoa 添加一个答案。

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

Twisted 很棒,但它是一个相当大的野兽,可能不是单线程异步 Telnet 编程的最佳介绍。MiniBoa 是一个轻量级的异步单线程 Python Telnet 实现,最初是为 mud 设计的,非常适合 OP 的问题。

于 2010-03-07T17:47:24.277 回答
3

为了真正轻松取胜,使用 SocketServer 和 SocketServer.ThreadingMixIn 实现您的解决方案

看看这个回显服务器示例,它看起来与您正在做的事情非常相似:http ://www.oreillynet.com/onlamp/blog/2007/12/pymotw_socketserver.html

于 2009-04-22T09:10:38.113 回答
2

如果您愿意接受一些概念上的挑战,我会考虑使用扭曲的。

作为扭曲的一部分,您的案例应该很容易实现。 http://twistedmatrix.com/projects/core/documentation/howto/servers.html

于 2009-04-22T08:06:46.100 回答
1

Use threading and then add the handler into a function. The thread will call every time a request i made:

Look at this

 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()
于 2013-08-10T21:53:34.770 回答
1

首先,购买 Comer 的TCP/IP 编程书籍。

在这些书中,Comer 将为服务器提供几种替代算法。有两种标准方法。

  • 每个请求的线程。

  • 按请求处理。

您必须选择这两者之一并实施。

在 thread-per 中,每个 telnet 会话都是整个应用程序中的一个单独线程。

在 process-per 中,您将每个 telnet 会话分叉到一个单独的子进程中。

您会发现在 Python 中处理每个请求的过程要容易得多,而且它通常可以更有效地使用您的系统。

Thread-per-request 适用于快速来去匆匆的事情(例如 HTTP 请求)。Telnet 有长时间运行的会话,其中子进程的启动成本不支配性能。

于 2009-04-22T15:10:49.513 回答
1

如果你想用纯python(无扭曲)来做,你需要做一些线程。如果您以前没有看过它,请查看: http ://heather.cs.ucdavis.edu/~matloff/Python/PyThreads.pdf

第 5/6 页左右是一个非常相关的示例;)

于 2009-04-22T12:00:17.677 回答
1

试试 MiniBoa 服务器?它恰好有 0 个依赖项,不需要扭曲或其他东西。MiniBoa 是一个非阻塞异步远程登录服务器,单线程,正是您所需要的。

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

于 2011-05-08T12:12:46.547 回答