网络基础

import socket
sk = socket.socket()
sk.bind(("192.16.12.3",8088))
sk.listen()
conn,addr = sk.accept()
conn.send(b""/"".encode("utf-8"))
ret = conn.recv(1024)
print(ret.decode("utf-8"))
conn.close()
sk.close()

import socket
sk = socket.socket()
sk.connect(("192.16.12.3",8088))
sk.send(b""/encode("utf-8"))
ret = sk.recv(1024)
print(ret.decode("utf-8"))
sk.close()

 以上是网络传输tcp协议的标准模式.

 

关于解决tcp传输文件中的黏包问题:

服务器端:

import socket
import json
import struct
sk = socket.socket()
sk.bind(("127.0.0.1",8001))
sk.listen()
conn,addr = sk.accept()
b_len_dic = conn.recv(4)
len_dic = struct.unpack('i',b_len_dic)[0]# 获取到int类型字典的长度,
# unpack得到的是一个元组,要取下标为0的位置
str_dic = conn.recv(len_dic).decode('utf-8')
# str_dic = {"opt":menu.get(num),"filename":None,"filesize":None}
dic = json.loads(str_dic)
if dic["opt"] == "upload":
    filename = "1"+ dic["filename"]
    with open(filename,"ab") as f:
        while dic['filesize']:
            content = conn.recv(1024)
            f.write(content)
            dic['filesize'] -= len(content)
conn.close()
sk.close()

客户端:

import socket
import os
import json
import struct
sk = socket.socket()
sk.connect(("127.0.0.1",8001))
menu = {"1":"upload","2":"download"}
for k,v in menu.items():
    print(k,v)
num = input("请输入功能选项:")
if num == "1":
    dic = {"opt":menu.get(num),"filename":None,"filesize":None}
    file_path = input("请输入一个绝对路径:")# 文件的绝对路径
    # E:\Python S14\day32\实现大文件的传输\11.mp4
    filename = os.path.basename(file_path)# 文件名字
    filesize = os.path.getsize(file_path)# 获取用户输入的路径中文件的大小
    dic["filename"] = filename
    dic["filesize"] = filesize
    str_dic = json.dumps(dic)
    len_dic = len(str_dic)# 获取到字典的长度,是一个int类型的数据   46   146
    b_len_dic = struct.pack('i',len_dic)# 用一个4bytes的数据表示字典的长度

    sk.send(b_len_dic + str_dic.encode("utf-8"))# 将bytes类型的字典的长度 + bytes类型的字典的内容,一起发送给服务器


    #  因为上边send字典时,如果程序执行过快,可能会马上执行到下边的send(content)
    #  此时有可能会发生粘包,所以在此中间加一个recv,为了避免粘包
    with open(file_path,"rb") as f:
        while filesize:
            content = f.read(1024)
            sk.send(content)
            filesize -= len(content)

需要注意的是struct模块的unpack解包得到的是只含一个传入结果的元组,可以利用索引提取出来.

转载于:https://www.cnblogs.com/smile568968/p/9456954.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值