2

我编写了以下函数,用于我用于测试的一组套接字实用程序中。(如果这很重要,请使用 Python 2.7.3。)我将库拉入其中的主要原因select是我可以实现超时,而不是永远等待响应。我发现的问题是响应在 2048 个字符处被截断,尽管使用 64K 作为.recv()套接字上方法的最大大小。在我参与之前,这种截断并没有发生select。当我将最大尺寸设置得更高时,它很高兴地通过了 64K 甚至更多。

我浏览了一些在线资源,select并找到了有关接收数据大小的明显上限的任何信息。即没有它存在的信息,更不用说如何修改它了。谁能指出我克服这个 2K 限制的方法?

    导入套接字,选择
    最大尺寸 = 65535
    超时 = 10

    def 瞬态连接(主机、端口、发送数据):
        错误,响应=假,''
        尝试:
            sendSocket = socket.socket()
            sendSocket.connect((主机,端口))
            sendSocket.send(sendData)
            gotData = select.select([sendSocket],[],[],TIMEOUT)
            如果(得到数据 [0]):
                响应 = sendSocket.recv(MAXSIZE)
            别的:
                错误=真
                response = '*** TIMEOUT ***\n主机没有响应。'
            sendSocket.close()
        除了异常,errText:
            错误,响应 = True,'*** SOCKET 错误 ***\n'+str(errText)
        返回(错误,响应)
4

2 回答 2

3

TCP 套接字为您提供双向字节流,但在较低级别,它是通过基于数据包的协议 (IP) 实现的。这意味着您可以在每次读取时接收任意流块(尽管字节都是按顺序排列的),具体取决于 TCP/IP 堆栈如何决定拆分流以进行传输。

这里的关键点是您必须recv()循环执行,直到获得完整的“应用程序消息”。引用Socket Programming HOWTO

现在我们来到套接字的主要绊脚石 -sendrecv在网络缓冲区上进行操作。它们不一定处理您交给它们的所有字节(或期望它们),因为它们的主要重点是处理网络缓冲区。通常,当相关的网络缓冲区已被填充(发送)或清空(接收)时,它们会返回。然后他们告诉你他们处理了多少字节。您有责任再次致电他们,直到您的信息得到完全处理

您在这里看到的是,select一旦有一些数据可用,就会提前通知您。

希望这可以帮助。

于 2013-01-24T17:15:24.373 回答
1

校正、测试和工作的功能:

    最大尺寸 = 65535
    超时 = 10
    def 瞬态连接(主机、端口、发送数据):
        错误,响应=假,''
        尝试:
            sendSocket = socket.socket()
            sendSocket.connect((主机,端口))
            sendSocket.send(sendData)
            gotData = select.select([sendSocket],[],[],TIMEOUT)
            如果(得到数据 [0]):
                响应 = sendSocket.recv(MAXSIZE)
                而真:
                    #一旦数据开始到达,使用更短的超时
                    gotData2 = select.select([sendSocket],[],[],0.5)
                    如果(得到数据2 [0]):
                        更多数据 = sendSocket.recv(MAXSIZE)
                        响应 += 更多数据
                    其他:休息
            别的:
                错误=真
                response = '*** TIMEOUT ***\n主机没有响应。'
            sendSocket.close()
        除了异常,errText:
            错误,响应 = True,'*** SOCKET 错误 ***\n'+str(errText)
        返回(错误,响应)

于 2013-01-25T01:44:07.830 回答