Python套接字不发送完整数据

时间:2013-12-30 19:38:52

标签: python sockets network-programming

我有一个客户端 - 服务器应用程序,其中客户端位于与我的服务器不同的盒子上。发送小数据包时,来自客户端的所有数据都会传送到服务器,反之亦然。客户端需要向服务器发送长度为43175字节的状态报告,服务器需要发送类似大小的指令。在43175字节数据包中,只有11711个字节进入服务器。

设置所有数据包,因此第一行是数据包的长度,以字节为单位,后跟数据包。

import socket, sys

# recv expects the first line to the the integer length of the following packet data
# this would look like
#
# 12
# Hello World!
#

def recv(socket):
    char = ''
    num = ''
    while char != '\n':
        num += char
        char = socket.recv(1)

        if char:
            dummy=1
        else:
            return False
    text = socket.recv(int(num))
    if sys.getsizeof(text) < int(num):
        print("The received packet was not the length the heading specified: " + str(sys.getsizeof(text)) + " ~ " + num)

    return text

“收到的数据包不是指定标题的长度:11711~43175”

发送过程如下所示 -

def emit(socket, packet):
    send = str(packet.length()) + "\n" + str(packet)
    socket.send(send)

# packet class in another file

import json, sys

class Packet:
    def __init__(self, name, data):
        self.name = name
        self.data = data

    def length(self):
        return sys.getsizeof(self.__str__())

    def __str__(self):
        obj = {"name":self.name,"data":self.data}
        return json.dumps(obj)

我还在客户端和服务器套接字上设置了一个逗留sockopt,但它没有帮助 -

self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect((self.host, self.port))

linger_struct = struct.pack("ii", 1, 10)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, linger_struct)

为什么会发生这种情况,我该怎么办呢?其他人有类似的问题吗?

2 个答案:

答案 0 :(得分:1)

使用TCP套接字时,无法保证收到您要求的所有信息,您可能会收到更少的信息。您可能必须在循环中接收以接收所有内容。

答案 1 :(得分:0)

从Joachim的建议和堆栈上发现的其他帖子溢出,recv长度只是可以接收的数量的上限。 recv不会等待在继续之前提取的数据量,因此它仍然不能满足我的需求。为了解决这个问题,我记录了我拉动的数量,而我拉的数量并不等于recv的预期循环量,直到我得到我期望的所有数据。

完美无瑕地工作。

感谢大家的帮助。

编辑:

还在代码中将所有sys.getsizeof更改为len(在recv和数据包中)。 sys.getsizeof无法正常工作。

def recv(socket):
    char = ''
    num = ''
    while char != '\n':
        num += char
        char = socket.recv(1)

        if char:
            dummy=1
        else:
            return False

    expectedlength = int(num)
    recvlength = 0

    text = ""
    while expectedlength-recvlength > 0:
        text += socket.recv(expectedlength-recvlength)
        recvlength = len(text)

    return text