zoukankan      html  css  js  c++  java
  • 网络基础

    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 S14day32实现大文件的传输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解包得到的是只含一个传入结果的元组,可以利用索引提取出来.

  • 相关阅读:
    python模块之linecache
    如何在cmd命令下运行python脚本
    Git remote: ERROR: missing Change-Id in commit message
    Git命令git update-index --assume-unchanged,忽略不想提交的文件(忽略跟踪)
    Git命令cherry-pick,选择把一部分代码提交到另一个分支
    Redis可以用来做什么?(摘自http://www.lianpenglin.cc廉鹏林博客)
    Yii笔记:打印sql、Form表单、时间插件、Mysql的 FIND_IN_SET函数使用、是否是post/ajax请求
    Yii1使用Gii生成模块实现CURD
    通过经纬度获取所属城市信息-php
    树莓派进阶之路 (010)
  • 原文地址:https://www.cnblogs.com/smile568968/p/9456954.html
Copyright © 2011-2022 走看看