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()
改正客户端

 

posted @ 2019-05-01 17:06  walle_zhao  阅读(1279)  评论(0编辑  收藏  举报