Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python套接字TCP截断消息_Python_Sockets_Tcp - Fatal编程技术网

Python套接字TCP截断消息

Python套接字TCP截断消息,python,sockets,tcp,Python,Sockets,Tcp,我有一个通信系统,每个用户都有一个tcp服务器和客户端。我必须使用计算机来测试我的系统。其思想是一个用户向另一个用户请求信息,然后接收该信息。但是当我从1号计算机到2号计算机做这件事的时候,它是工作的,但是另一种方式是不工作的,信息被截断了。以下是相关代码: server.py def handle_client(conn, addr): connected = True while connected: msg_length = conn.recv(HEADER).decode(FO

我有一个通信系统,每个用户都有一个tcp服务器和客户端。我必须使用计算机来测试我的系统。其思想是一个用户向另一个用户请求信息,然后接收该信息。但是当我从1号计算机到2号计算机做这件事的时候,它是工作的,但是另一种方式是不工作的,信息被截断了。以下是相关代码:
server.py

def handle_client(conn, addr):
connected = True

while connected:
    msg_length = conn.recv(HEADER).decode(FORMAT)

    if msg_length:
        msg_length = int(msg_length)
        msg = conn.recv(msg_length).decode(FORMAT)

        if msg == DISCONNECT_MESSAGE:
            connected = False

        elif msg == "REQBLOCKCHAIN":
            print(f"Blockchain request from {addr}")
            addr_s = addr[0]
            print(addr_s)
            conn.send("Chain successfully requested.".encode(FORMAT))
            send_chain(addr_s)
            

        elif msg == "BLOCKCHAIN":
            print(f"Blockchain received from {addr}")
            print(threading.active_count())
            chain_length = conn.recv(HEADER).decode(FORMAT)

            if chain_length:
                chain_length = int(chain_length)
                chain_recv = conn.recv(chain_length)
                print("b")
                print(chain_recv)
                chain = chain_recv.decode(FORMAT)
                print(chain_length)
                print(chain)
                print(len(chain_recv))
                chain_dict = json.loads(fix_text(chain))
                print(chain_dict[-1])
                chain_is_valid = is_chain_valid(chain_dict)
                if chain_is_valid:
                    try:
                        with open("data/blockchain.json") as og_chain_file:
                            og_chain = json.load(og_chain_file)
                        if og_chain == chain_dict:
                            conn.send("Same".encode(FORMAT))
                            return "Same"
                        else:
                            if og_chain[-1]['index'] < chain_dict[-1]['index']:
                                with open("data/blockchain.json", "w") as chain_file:
                                    json.dump(chain_dict, chain_file)
                                conn.send("Chain successfully broadcasted.".encode(FORMAT))
                                return "Blockchian updated"
                            else:
                                conn.send("Same or newer".encode(FORMAT))
                                return "Same or newer"
                    except FileNotFoundError:
                        conn.send("Blockchain data file missing".encode(FORMAT))
                        return "Blockchain data file missing"
                else:
                    err = {'message' : 'Received chain is not valid !',
                           'ip_sender': addr[0]}
                    conn.send(json.dumps(err).encode(FORMAT))
                    return err
conn.close()
def req_blockchain(addr):
    HEADER = 64
    PORT = 5050
    FORMAT = 'utf-8'
    ADDR = (addr, PORT)

    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(ADDR)


    msg_length = len("REQBLOCKCHAIN")
    send_length = str(msg_length).encode(FORMAT)
    send_length += b' ' * (HEADER - len(send_length))
    client.send(send_length)
    client.send("REQBLOCKCHAIN".encode(FORMAT))
    print(client.recv(2048).decode(FORMAT))

def send_chain( addr):
    HEADER = 64
    PORT = 5050
    FORMAT = 'utf-8'
    ADDR = (addr, PORT)
    print(ADDR)

    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(ADDR)

    msg_length = len("BLOCKCHAIN".encode(FORMAT))
    send_type_length = str(msg_length).encode(FORMAT)
    send_type_length += b' ' * (HEADER - len(send_type_length))
    print(send_type_length.decode(FORMAT) + "ok")
    client.send(send_type_length)
    client.send("BLOCKCHAIN".encode(FORMAT))
    with open("data/blockchain.json") as chain_file:
        chain = json.load(chain_file)
    chain_se = json.dumps(chain)
    print(chain_se)
    chain_msg = chain_se.encode(FORMAT)
    msg_length = len(chain_msg)
    send_length = str(msg_length).encode(FORMAT)
    send_length += b' ' * (HEADER - len(send_length))
    client.send(send_length)
    client.send(chain_msg)
    print(client.recv(2048).decode(FORMAT))

我有大量的print语句用于调试,基本上长度不错,但是消息被截断了。计算机1将功能req_区块链调用到计算机2,然后一切都是自动的。与1一起工作,从2请求,但不是另一种奇怪的方式。信息被剪切的位置每次都会改变。在发送端,消息已满,在接收端,消息被截断。

似乎您在客户端启动了两次连接。一次进入请求链,一次进入发送链。我猜你的“如果”状态不正确,无法将其发回。查看带有-client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)的行,TCP不使用或不理解“消息”。这是一条小溪。如果发送1024个字节,收件人可能会收到10个字节,然后在最后一次
read()
上收到1000个字节,然后收到14个字节。没有消息边界。您需要知道需要多少字节,然后在循环中读取,直到得到所有字节。@MarkSetchell解决了这个问题,addind a loop,thanksAlso seek
socket.makefile
,它用
.read()
.readline()
方法将套接字包装在一个类似文件的对象中,这些方法缓冲套接字并读取请求的字节数(除非关闭)或分别读取换行符。