1. 程式人生 > >tcp協議之recv

tcp協議之recv

ket encode with open tin int -a sha name closed

寫一個下載功能的時候遇到的一個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()
改正客戶端

tcp協議之recv