Python SocketServer连接超时

4

我是一名刚接触 Python Socket 编程的人。我正在尝试创建一个简单的聊天应用程序,想要通过客户端程序向服务器发送数据,但是在服务器接收数据时,我遇到了“超时”错误。

我的客户端程序:

import socket
PORT = 3017

def handler(req):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect(("localhost", PORT))
    except socket.error, msg:
        print("error connecting socket")
        s = None
    finally:
        f.close()
    s.settimeout(10.0)
    s.send(req)
    line = s.recv(1024)
    s.close()
    return line


if __name__ == '__main__':
    while(1):
        input = raw_input(">")
        resp = handler(input)
        print resp

我的服务器程序-

import socket
import SocketServer

class echo_server(SocketServer.StreamRequestHandler):
    def handle(self):
        timeout_telnet = float(2.0)
        self.connection.settimeout(timeout_telnet)

        data = []
        # Read in all the lines.
        while 1:
            try:
                line = self.rfile.readline()
            except BaseException, e:
                # Timeout.
                print("error", e)
                break
            data.append(line)
            print("data in handle method-\n", data)
            self.wfile.write(("echo data- ".join(data)))
            break

        # Goodbye


def main():
    s = SocketServer.ThreadingTCPServer(("", 3017), echo_server)
    try:
        s.serve_forever()
    except KeyboardInterrupt:
        print("Shutting down.")
        s.socket.close() 

if __name__ == "__main__":
    main()

也许 [https://docs.python.org/2/howto/sockets.html] 是一个不错的起点。 - CristiFati
2个回答

2
你的问题是在使用流套接字时需要控制消息长度。
发生了什么事:
你的客户端发送了一些数据(N 字节)。 你的服务器从套接字中读取数据,但它不知道你的“消息”是否完整或是否还有其他数据将被发送。
你可以怎么做? 如果你将

替换为

,那么你就可以通过读取每个段落来确保消息已完全接收。

self.rfile.readline()

使用self.request.recv(10) - 您的服务器将读取10个字节并将它们发送回来。因此,您可以为服务器和客户端彼此发送的消息设置一些消息大小。
此外,这里还有一些有用的信息: https://docs.python.org/2/howto/sockets.html#using-a-socket 下面是最简单聊天的示例: 客户端
def handler(req):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(("localhost", PORT))
    message = req
    s.send(req)
    print s.recv(1024)
    s.close()

服务器
def handle(self):
    while True:
        line = self.request.recv(1024)
        if line:
            print("data in handle method-\n", line.strip())
            self.wfile.write(line)

但是可能你以后会遇到一些问题,Python文档可以帮助你理解它的工作原理。

将self.rfile.readline()替换为self.request.recv(10),仍然出现相同的错误,但是如果我写self.request.recv(),那么我最多接收10个字符的数据,并且我会收到这个错误recv()至少需要1个参数(未给出0)。我明白函数需要一个参数,但我不明白的是,只要我给出一些参数,为什么就会出现超时异常。 - taher ali rangwala

0
真正的问题是服务器在等待客户端发送更多消息,导致超时。我已经找到了一个可行的解决方案。在客户端程序中添加这一行即可:
s.shutdown(1)

之后

s.send(req)

并在服务器程序中替换

line = self.rfile.readline()

使用

line = self.request.recv(1024)

shutdown(1) 告诉服务器:“此客户端已完成发送,但仍可接收。”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接