zoukankan      html  css  js  c++  java
  • python------Socket网络编程(二)粘包问题

    一.socket网络编程

     粘包:服务端两次发送指令在一起,它会把两次发送内容合在一起发送,称为粘包,从而出现错误。

    解决方法:(比较low的方法)

    有些需要实时更新的,用sleep有延迟,不能这样解决问题。

    解决方法之高级方法:

    客户端:

    二.发送文件

    ftp server端有哪几步呢?

    ①读取客户端发过来的文件名

    ②检测文件是否存在

    ③打开文件

    ④检测文件大小

    ⑤发送文件大小给客户端

    ⑥等待客户端确认

    ⑦开始边读边发数据

    ⑧发送md5

     1 import socket
     2 import os
     3 import time
     4 import hashlib
     5 server = socket.socket()
     6 server.bind(('localhost',3333))
     7 
     8 server.listen()
     9 
    10 while True:
    11     conn,addr = server.accept()
    12     print("new conn:",addr)
    13     while True:
    14         print("等待新指令")
    15         data = conn.recv(1024)
    16         if not data:
    17             print("客户端已断开")
    18             break
    19         cmd,filename = data.decode().split()
    20         print(filename)
    21         if os.path.isfile(filename):
    22             f = open(filename,"rb")
    23             m = hashlib.md5()
    24             file_size = os.stat(filename).st_size  #在os模块中获取文件大小
    25             conn.send(str(file_size).encode())   #发送文件大小
    26             conn.recv(1024)   #wait  for ack
    27             for line in f:
    28                 m.update(line)
    29                 conn.send(line)
    30             print("file md5",m.hexdigest())
    31             f.close()
    32             conn.send(m.hexdigest().encode()) #send md5
    33 
    34         print("执行指令:", data)
    35 
    36 server.close()

    客户端:

     1 import socket
     2 import hashlib
     3 client = socket.socket()
     4 client.connect(('localhost',3333))
     5 
     6 while True:
     7     cmd = input(">>:").strip()   #cmd = input(b">>:").strip()如果前面直接加b,则只能传英文
     8     if len(cmd) == 0 : continue
     9     if cmd.startswith("get"):
    10         client.send(cmd.encode())
    11         server_response = client.recv(1024)
    12         print("server response:",server_response)
    13         client.send("ready to recv file".encode())
    14         file_total_size = int(server_response.decode())
    15         received_size = 0
    16         filename = cmd.split()[1]
    17         f = open("wenjian","wb")
    18         m = hashlib.md5()
    19 
    20         while received_size<file_total_size:
    21             #下面这段代码彻底解决粘包问题
    22             if file_total_size - received_size > 1024:  #要收不止一次
    23                 size = 1024
    24             else:
    25                 size = file_total_size - received_size #最后一次了,剩多少收多少
    26                 print("last receive:",size)
    27 
    28             data = client.recv(1024)
    29             received_size += len(data)
    30             m.update(data)
    31             f.write(data)
    32             print(file_total_size,received_size)  #看演示效果
    33         else:
    34             new_file_md5 = m.hexdigest()
    35             print("file received done",received_size,file_total_size)
    36             f.close()
    37         server_file_md5 = client.recv(1024)
    38         print("server file md5:",server_file_md5)
    39         print("client file md5:", new_file_md5)
    40 
    41 
    42 client.close()

    具体用的时候在钻研吧。

  • 相关阅读:
    Python-炫酷二维码
    Dictionary 序列化与反序列化
    获取数据库所有表名与字段名
    LinQ To Object 基本用法
    使用jq操作脚本生成元素的事件
    表单验证如何让select设置为必选
    js实现复制功能兼容ios
    微信小程序使用函数防抖解决重复点击消耗性能问题
    electronr进行签名与公证
    使用electron在mac升级签名后进行升级出现“QRLUpdaterErrorDomain”的错误
  • 原文地址:https://www.cnblogs.com/bltstop/p/9898954.html
Copyright © 2011-2022 走看看