套接字上的服务器响应被截断为2K

时间:2013-01-24 16:25:09

标签: sockets python-2.7 client

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

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

    import socket,select
    MAXSIZE = 65535
    TIMEOUT = 10

    def transientConnect(host,port,sendData):
        error,response = False,''
        try:
            sendSocket = socket.socket()
            sendSocket.connect((host,port))
            sendSocket.send(sendData)
            gotData = select.select([sendSocket],[],[],TIMEOUT)
            if (gotData[0]):
                response = sendSocket.recv(MAXSIZE)
            else:
                error    = True
                response = '*** TIMEOUT ***\nNo response from host.'
            sendSocket.close()
        except Exception, errText:
            error,response = True,'*** SOCKET ERROR ***\n'+str(errText)
        return (error,response)

2 个答案:

答案 0 :(得分:3)

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

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

现在我们来到套接字的主要障碍 - sendrecv对网络缓冲区进行操作。它们不一定处理你所处理的所有字节(或期望它们),因为它们主要关注的是处理网络缓冲区。通常,它们在关联的网络缓冲区已填充(发送)或清空(recv)时返回。然后他们告诉你他们处理了多少字节。 你的责任再次打电话给你,直到你的信息被完全处理完毕。

您在此处看到的是,只要某些数据可用,select就会提前通知您。

希望这有帮助。

答案 1 :(得分:1)

经过纠正,测试和运作的功能:


    MAXSIZE = 65535
    TIMEOUT = 10
    def transientConnect(host,port,sendData):
        error,response = False,''
        try:
            sendSocket = socket.socket()
            sendSocket.connect((host,port))
            sendSocket.send(sendData)
            gotData = select.select([sendSocket],[],[],TIMEOUT)
            if (gotData[0]):
                response = sendSocket.recv(MAXSIZE)
                while True:
                    #Once data starts arriving, use a shorter timeout
                    gotData2 = select.select([sendSocket],[],[],0.5)
                    if (gotData2[0]):
                        moreData = sendSocket.recv(MAXSIZE)
                        response += moreData
                    else:break
            else:
                error    = True
                response = '*** TIMEOUT ***\nNo response from host.'
            sendSocket.close()
        except Exception, errText:
            error,response = True,'*** SOCKET ERROR ***\n'+str(errText)
        return (error,response)