我目前正在用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()
感谢您的帮助。
答案 0 :(得分: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.
说真的,谈到异步网络,扭曲是可行的方法。它以单线程单进程方法处理多个连接。
答案 1 :(得分:4)
您需要某种形式的异步套接字IO。看一下this explanation,它讨论了低级套接字术语中的概念,以及用Python实现的相关示例。这应该指向正确的方向。
答案 2 :(得分:4)
回复迟到,但唯一的答案是扭曲或线程(哎哟),我想为MiniBoa添加答案。
http://code.google.com/p/miniboa/
扭曲很棒,但它是一个相当大的野兽,可能不是单线程异步Telnet编程的最佳介绍。 MiniBoa是一个轻量级的异步单线程Python Telnet实现,最初是为泥浆设计的,完全符合OP的问题。
答案 3 :(得分:3)
使用SocketServer& amp; SocketServer.ThreadingMixIn
看看这个echo服务器示例,看起来与你正在做的事情非常相似:http://www.oreillynet.com/onlamp/blog/2007/12/pymotw_socketserver.html
答案 4 :(得分:2)
如果你有一些概念上的挑战,我会考虑使用扭曲。
作为扭曲的一部分,你的案子应该是微不足道的。 http://twistedmatrix.com/projects/core/documentation/howto/servers.html
答案 5 :(得分:1)
如果你想用纯python(sans-twisted)来做,你需要做一些线程。如果你以前看过它,请查看: http://heather.cs.ucdavis.edu/~matloff/Python/PyThreads.pdf
第5/6页附近的是非常相关的示例;)
答案 6 :(得分:1)
首先,在TCP/IP programming上购买Comer的书籍。
在这些书中,Comer将为服务器提供多种替代算法。有两种标准方法。
主题的每次请求。
过程的每次请求。
你必须选择其中一个并实现它。
在thread-per中,每个telnet会话都是整个应用程序中的一个单独的线程。
在process-per中,您将每个telnet会话分成一个单独的子进程。
您会发现在Python中处理每个请求的过程要容易得多,而且通常可以更有效地使用您的系统。
每个请求的线程适用于快速进入的事物(如HTTP请求)。 Telnet具有长时间运行的会话,其中子进程的启动成本不会影响性能。
答案 7 :(得分:1)
试试MiniBoa服务器?它有0个依赖项,不需要扭曲或其他东西。 MiniBoa是一个非阻塞的异步telnet服务器,单线程,正是你所需要的。
答案 8 :(得分:1)
使用线程,然后将处理程序添加到函数中。每次请求时,线程都会调用:
看看这个
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()