多个同时网络连接 - Telnet 服务器,Python
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/776120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multiple simultaneous network connections - Telnet server, Python
提问by SpleenTea
I'm currently writing a telnet server in Python. It's a content server. People would connect to the server via telnet, and be presented with text-only content.
我目前正在用 Python 编写一个 telnet 服务器。这是一个内容服务器。人们将通过 telnet 连接到服务器,并看到纯文本内容。
My problem is that the server would obviously need to support more than one simultaneous connection. The current implementation I have now supports only one.
我的问题是服务器显然需要支持多个同时连接。我现在的当前实现只支持一个。
This is the basic, proof-of-concept server I began with (while the program has changed greatly over time, the basic telnet framework hasn't):
这是我开始使用的基本概念验证服务器(虽然程序随着时间的推移发生了很大变化,但基本的 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()
Thanks for your help.
谢谢你的帮助。
回答by nosklo
Implemented in 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()
Testing:
测试:
$ 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.
Seriously, when it comes to asynchronous network, twisted is the way to go. It handles multiple connections in a single-thread single-process approach.
说真的,当谈到异步网络时,twisted 是要走的路。它以单线程单进程的方式处理多个连接。
回答by georgek
Late for the reply, but with the only answers being Twisted or threads (ouch), I wanted to add an answer for MiniBoa.
回复晚了,但唯一的答案是 Twisted 或线程(哎哟),我想为 MiniBoa 添加一个答案。
http://code.google.com/p/miniboa/
http://code.google.com/p/miniboa/
Twisted is great, but it's a rather large beast that may not be the best introduction to single-threaded asynchronous Telnet programming. MiniBoa is a lightweight, asynchronous single-threaded Python Telnet implementation originally designed for muds, which suits the OP's question perfectly.
Twisted 很棒,但它是一个相当大的野兽,可能不是单线程异步 Telnet 编程的最佳介绍。MiniBoa 是一个轻量级的、异步的单线程 Python Telnet 实现,最初是为 muds 设计的,非常适合 OP 的问题。
回答by Brian Agnew
You need some form of asynchronous socket IO. Have a look at this explanation, which discusses the concept in low-level socket terms, and the related examples which are implemented in Python. That should point you in the right direction.
您需要某种形式的异步套接字 IO。看看这个解释,它讨论了低级套接字术语中的概念,以及在 Python 中实现的相关示例。这应该为您指明正确的方向。
回答by Ravi
For a really easy win implement you solution using SocketServer & the SocketServer.ThreadingMixIn
使用 SocketServer 和 SocketServer.ThreadingMixIn 实现真正简单的解决方案
have a look a this echo server example it looks quite similar to what you're doing anyway: http://www.oreillynet.com/onlamp/blog/2007/12/pymotw_socketserver.html
看看这个回声服务器示例,它看起来与您正在做的事情非常相似:http: //www.oreillynet.com/onlamp/blog/2007/12/pymotw_socketserver.html
回答by Trey Stout
If you're up for a bit of a conceptual challenge, I'd look into using twisted.
如果您想接受一些概念上的挑战,我会考虑使用扭曲。
Your case should be trivial to implement as a part of twisted. http://twistedmatrix.com/projects/core/documentation/howto/servers.html
作为扭曲的一部分,您的案例应该很容易实现。 http://twistedmatrix.com/projects/core/documentation/howto/servers.html
回答by amanita
Try MiniBoa server? It has exactly 0 dependencies, no twisted or other stuff needed. MiniBoa is a non-blocking async telnet server, single threaded, exactly what you need.
试试 MiniBoa 服务器?它恰好有 0 个依赖项,不需要扭曲或其他东西。MiniBoa 是一个非阻塞异步 telnet 服务器,单线程,正是您所需要的。
回答by Vogon Jeltz
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()
回答by Alex
If you want to do it in pure python (sans-twisted), you need to do some threading. If you havnt seen it before, check out: http://heather.cs.ucdavis.edu/~matloff/Python/PyThreads.pdf
如果你想用纯python(sans-twisted)来做,你需要做一些线程。如果您以前没有看过,请查看:http://heather.cs.ucdavis.edu/~matloff/Python/PyThreads.pdf
around page 5/6 is an example that is veryrelevant ;)
第 5/6 页左右是一个非常相关的例子;)
回答by S.Lott
First, buy Comer's books on TCP/IP programming.
首先,购买 Comer 的TCP/IP 编程书籍。
In those books, Comer will provide several alternative algorithms for servers. There are two standard approaches.
在这些书中,Comer 将为服务器提供几种替代算法。有两种标准方法。
Thread-per-request.
Process-per-request.
每个请求的线程。
处理每个请求。
You must pick one of these two and implement that.
您必须选择这两个中的一个并实施它。
In thread-per, each telnet session is a separate thread in your overall application.
在 thread-per 中,每个 telnet 会话都是整个应用程序中的一个单独线程。
In process-per, you fork each telnet session into a separate subprocess.
在 process-per 中,您将每个 telnet 会话分叉到一个单独的子进程中。
You'll find that process-per-request is much, much easier to handle in Python, and it generally makes more efficient use of your system.
您会发现在 Python 中处理每个请求要容易得多,而且通常可以更有效地利用您的系统。
Thread-per-request is fine for things that come and go quickly (like HTTP requests). Telnet has long-running sessions where the startup cost for a subprocess does not dominate performance.
Thread-per-request 适用于来去匆匆的事物(如 HTTP 请求)。 Telnet 具有长时间运行的会话,其中子进程的启动成本不会影响性能。