1

我想使用 Python 脚本实现 TCP 服务器。

服务器基本上应该完成以下任务:

它将由远程客户端循环轮询,然后读取其本地工作站上的某些数据并将其发送到客户端轮询。

可以假设如下:

  • 始终只有一个客户端连接到服务器(通过以太网)
  • 客户端和服务器运行在 Windows 平台上
  • Python 2.5.1 将用于实现

目标:

  • 服务器应该尽可能高效地从/向客户端读取/写入数据
  • 服务器应尽可能减少本地工作站的压力
  • 服务器不得造成系统不稳定

由于我对该主题只有一点经验,因此我想在这里讨论如何优化我当前的(非常简单的)代码以满足前面提到的要求。

到目前为止,我有以下内容:

import socket
import sys

port_number = 12345
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_address = (socket.gethostname(), port_number)
sock.bind(server_address)

sock.listen(1)
while True:
    connection, client_address = sock.accept()
    try:
        while True:
            data = connection.recv(4096)
            if data:
                connection.sendall(getdesireddata(data))
            else:
                break
    finally:
        connection.close()

感谢您的所有回复。

4

1 回答 1

3

首先,代码中存在小错误。线...

data = connection.recv(4096)

...将尝试从单个 TCP 数据包中读取多达 4k 的数据,但如果客户端发送的数据超过 4k,或者决定将数据分成几个数据包,您可能无法在一次调用中获得所有数据。

您通常会继续从套接字读取数据,附加到缓冲区,直到您拥有协议规范定义的完整消息,或者直到远程主机关闭其 TCP 连接的出站一半。

如果客户端崩溃并且没有正确关闭套接字,您还会遇到服务器卡住的问题。为避免这种情况,您需要查看任一非阻塞 IO,类似于...

connection.setblocking(0)
buffer = ''
while 1:        
    try:
        data = connection.recv(4096)
        if not data:
            # Client has closed outbound connection
            break
        else:
            # Append to buffer
            buffer += data
    except socket.error, e:
        code = e.args[0]
        if code == 11:
            # Got EWOULDBLOCK/EAGAIN
            time.sleep(0.1)
        else:
            # Got another error
            raise
do_something_with(buffer)

...或者看看使用 Python选择模块来做同样的事情。

关于性能的次要问题,我看不出你可以用这么小的代码示例做出任何重大改进。

于 2013-04-13T13:46:37.490 回答