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()

具体用的时候在钻研吧。

原文地址:https://www.cnblogs.com/bltstop/p/9898954.html