• tcp协议之recv


    写一个下载功能的时候遇到的一个bug。

    import socket
    import struct
    import json
    import os
    base_dir = os.getcwd()
    print(base_dir)
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(("127.0.0.1", 8889))
    while True:
        msg = input(">>:")
        if not msg:
            continue
        client.send(msg.encode("utf-8"))
        heard_data = client.recv(4)
        heard_len = struct.unpack("i", heard_data)[0]
    
        heard_bytes = client.recv(heard_len)
        heard = json.loads(heard_bytes.decode("utf-8"))
        filename = heard["filename"]
        md5 = heard["md5"]
        filesize = heard["filesize"]
        data = b""
        recv_size = 0
        while filesize > 0:  # 判断条件为什么不能使用while filesize > 0:
            msg = client.recv(1024)
            print(len(msg))
            data += msg
            filesize -= 1024   # 这里的一个问题,为什么不能使用filesize -= 1024
        with open("{}/test/downloads/{}".format(base_dir, filename), "wb") as f:
            f.write(data)
        print("下载成功")
    client.close()
    client
    import socket
    import os
    import struct
    import json
    base_dir = os.getcwd()
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(("127.0.0.1", 8889))
    server.listen(5)
    while True:
        client,address = server.accept()
        while True:
            try:
                cmd_recv = client.recv(1024)
                if not cmd_recv:
                    break
                cmd = cmd_recv.decode("utf-8")
                filename = cmd.split()[1]
                filesize = os.path.getsize("{}/test/share/{}".format(base_dir, filename))
                print(filesize)
                heard = {
                    "filename": filename,
                    "filesize": filesize,
                    "md5": "xxxx",
                }
                heard_str = json.dumps(heard)
                heard_len = struct.pack("i", len(heard_str))
                client.send(heard_len)
                client.send(heard_str.encode("utf-8"))
                with open("{}/test/share/{}".format(base_dir, filename), "rb") as f:
                    for line in f:
                        client.send(line)
            except Exception as e:
                print(e)
                break
        client.close()
    server.close()
    server

    这里是客户端的问题,就是在recv的时候,每次接收1024个,但是实际上可能发送的并没有1024个,这个时候recv并不会一直等待着,而在一定的时间之后能接受多少先接收多少。

    所以,这里在print(len(msg))的时候,就会发现中间有一些是没有达到1024个字符。

    因此下面filesize -= 1024就是错误的。改正过来的客户端代码如下:

    import socket
    import struct
    import json
    import os
    base_dir = os.getcwd()
    print(base_dir)
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(("127.0.0.1", 8889))
    while True:
        msg = input(">>:")
        if not msg:
            continue
        client.send(msg.encode("utf-8"))
        heard_data = client.recv(4)
        heard_len = struct.unpack("i", heard_data)[0]
    
        heard_bytes = client.recv(heard_len)
        heard = json.loads(heard_bytes.decode("utf-8"))
        filename = heard["filename"]
        md5 = heard["md5"]
        filesize = heard["filesize"]
        data = b""
        recv_size = 0
        while filesize > 0:  # 判断条件为什么不能使用while filesize > 0:
            msg = client.recv(1024)
            data += msg
            filesize -= len(msg)  # 这里的一个问题,为什么不能使用filesize -= 1024
        with open("{}/test/downloads/{}".format(base_dir, filename), "wb") as f:
            f.write(data)
        print("下载成功")
    client.close()
    改正客户端
  • 相关阅读:
    java中给集合快速取值最大值和最小值
    Mybatis.xml文件中大于小于等于
    Validate表单验证
    更新了svn 后,某个文件多了几个副本如:xxx.r1 xxx.r3 xxx.mine等,正常文件名xxx
    Oracle监听出现的问题总结,以及解决办法
    oracle三个网络配置文件(listener.ora、tnsname.ora、sqlnet.ora)的作用
    Lucene提供的条件判断查询
    Lucene 单域多条件查询
    lucene自定义过滤器
    luke使用
  • 原文地址:https://www.cnblogs.com/walle-zhao/p/10800199.html
Copyright © 2020-2023  润新知