在 socket 服务器运行时如何执行其他代码?

2 投票
3 回答
7004 浏览
提问于 2025-04-17 02:18

我想知道怎么才能让一个套接字服务器运行起来,能够接受新的连接,同时又不让处理新连接的代码一直卡在同一个循环里。

我刚开始学习这个,TCP处理器会有用吗?

我只需要一些简单的例子,想要在服务器里有一个命令部分,这样我就可以在服务器运行的时候做一些事情。

编辑:我想做的事情是:

1 - TCP server for multiple clients
2 - Respond to more than one at a time when needed
3 - Text input availability at all time, to be used for getting/setting info
4 - A simple way to get/save client address info. Currently using a list to save them. 

3 个回答

0

我不太确定你具体在问什么,但通常在服务器端,你会使用socket()、bind()和listen()这些函数来设置一个套接字,然后在一个循环中调用accept()。这个accept()调用会一直等待,直到有客户端连接进来。

对于简单的服务器,你可以在这个循环中处理客户端的请求。对于实际的服务器,你需要启动其他的机制(比如新的线程或进程,具体取决于你使用的语言或平台)来异步处理请求,这样原来的循环就可以继续执行accept()调用,继续监听新的连接。

想了解更多信息和Python的示例,可以查看Python的套接字文档:

http://docs.python.org/howto/sockets.html

2

你可以在一个线程中运行你的套接字服务器。

import threading
import SocketServer

server = SocketServer.TCPServer(('localhost', 0), SocketServer.BaseRequestHandler)
th = threading.Thread(target=server.serve_forever)
th.daemon = True
th.start()
0

Python内置了对异步套接字处理的支持,这个功能在asyncore模块里可以找到(http://docs.python.org/library/asyncore.html)。

异步套接字处理的意思是,你的代码里必须至少执行一次套接字处理循环的迭代(也就是主循环):

asyncore.loop(count=1)

下面这个例子是从文档中摘取的:

import asyncore
import socket

class EchoHandler(asyncore.dispatcher_with_send):

    def handle_read(self):
        data = self.recv(8192)
        if data:
            self.send(data)

class EchoServer(asyncore.dispatcher):

    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind((host, port))
        self.listen(5)

    def handle_accept(self):
        pair = self.accept()
        if pair is None:
            pass
        else:
            sock, addr = pair
            print('Incoming connection from %s' % repr(addr))
            handler = EchoHandler(sock)

server = EchoServer('localhost', 8080)
# Note that here loop is infinite (count is not given)
asyncore.loop()

每当套接字接受到一个连接时,循环会调用handle_accept。每当有数据可以从套接字读取时,循环会调用handle_read,依此类推。

你可以用这种方式同时处理TCP和UDP套接字。

撰写回答