zoukankan      html  css  js  c++  java
  • 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()
    改正客户端
  • 相关阅读:
    SlidingMenu和ActionBarSherlock结合滑动式菜单都
    Actionbarsherlock 简明教程
    Ajax表单提交插件jquery form
    form 转json最佳示例
    构造AJAX参数, 表单元素JSON相互转换
    jquery序列化form表单使用ajax提交后处理返回的json数据
    firefox插件poster的使用,发起自定义http请求
    android学习8(ListView高级使用)
    Linux server关闭自己主动
    阅读安卓在线(Android)系统源代码
  • 原文地址:https://www.cnblogs.com/walle-zhao/p/10800199.html
Copyright © 2011-2022 走看看