09-18-周四_10-40-47
This commit is contained in:
@@ -553,6 +553,67 @@ phone.close()
|
|||||||
|
|
||||||
## 粘包的解决方案
|
## 粘包的解决方案
|
||||||
|
|
||||||
|
### 添加结束字符
|
||||||
|
|
||||||
|
在每次发送一个信息结束的地方,添加一个标识,在从缓冲区获取数据时候,根据表示来判断消息是否已经获取结束
|
||||||
|
|
||||||
|
- 服务端
|
||||||
|
|
||||||
|
```python
|
||||||
|
import socket
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
|
||||||
|
phone.bind(('127.0.0.1', 8080))
|
||||||
|
|
||||||
|
phone.listen(5)
|
||||||
|
|
||||||
|
while 1: # 循环连接客户端
|
||||||
|
conn, client_addr = phone.accept()
|
||||||
|
print(client_addr)
|
||||||
|
|
||||||
|
while 1:
|
||||||
|
try:
|
||||||
|
cmd = conn.recv(1024)
|
||||||
|
ret = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
correct_msg = ret.stdout.read()
|
||||||
|
error_msg = ret.stderr.read()
|
||||||
|
conn.send(correct_msg + error_msg + "結束".encode("gbk"))
|
||||||
|
except ConnectionResetError:
|
||||||
|
break
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
phone.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
- 客户端
|
||||||
|
|
||||||
|
```python
|
||||||
|
import socket
|
||||||
|
|
||||||
|
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 买电话
|
||||||
|
|
||||||
|
phone.connect(('127.0.0.1',8080)) # 与客户端建立连接, 拨号
|
||||||
|
|
||||||
|
|
||||||
|
while 1:
|
||||||
|
cmd = input('>>>')
|
||||||
|
phone.send(cmd.encode('utf-8'))
|
||||||
|
|
||||||
|
from_server_data = b""
|
||||||
|
while True:
|
||||||
|
from_server_data += phone.recv(1024)
|
||||||
|
if from_server_data.decode('gbk').count("結束") > 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
print(from_server_data.decode('gbk'))
|
||||||
|
|
||||||
|
phone.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
- 这样只是解决了一次消息没有收完整的情况,但是一次接受1024,可能会将紧跟的下一条消息的开头也一并接收了
|
||||||
|
|
||||||
### struct模块
|
### struct模块
|
||||||
|
|
||||||
该模块可以把一个类型,如数字,转成固定长度的bytes
|
该模块可以把一个类型,如数字,转成固定长度的bytes
|
||||||
@@ -570,6 +631,8 @@ ret1 = struct.unpack('i',ret)[0]
|
|||||||
print(ret1, type(ret1), len(ret1))
|
print(ret1, type(ret1), len(ret1))
|
||||||
|
|
||||||
# 但是通过struct 处理不能处理太大
|
# 但是通过struct 处理不能处理太大
|
||||||
|
# 可处理的范围是 -2,147,483,648 ~ 2,147,483,647(即 -2³¹ ~ 2³¹-1)。
|
||||||
|
# 如果超出范围,就会发生异常,struct.error
|
||||||
```
|
```
|
||||||
|
|
||||||
方案一:
|
方案一:
|
||||||
@@ -643,7 +706,12 @@ while 1:
|
|||||||
res = b''
|
res = b''
|
||||||
|
|
||||||
while recv_size < total_size:
|
while recv_size < total_size:
|
||||||
recv_data = phone.recv(1024)
|
# 精准的获取数据的长度,防止将后面跟着的数据头部获取到
|
||||||
|
if (total_size - recv_size) > 1024:
|
||||||
|
recv_buffer = 1024
|
||||||
|
else:
|
||||||
|
recv_buffer = total_size - recv_size
|
||||||
|
recv_data = phone.recv(recv_buffer)
|
||||||
res += recv_data
|
res += recv_data
|
||||||
recv_size += len(recv_data)
|
recv_size += len(recv_data)
|
||||||
|
|
||||||
@@ -757,13 +825,19 @@ while 1:
|
|||||||
res = b''
|
res = b''
|
||||||
|
|
||||||
while recv_size < total_size:
|
while recv_size < total_size:
|
||||||
recv_data = phone.recv(1024)
|
# 精准的获取数据的长度,防止将后面跟着的数据头部获取到
|
||||||
|
if (total_size - recv_size) > 1024:
|
||||||
|
recv_buffer = 1024
|
||||||
|
else:
|
||||||
|
recv_buffer = total_size - recv_size
|
||||||
|
recv_data = phone.recv(recv_buffer)
|
||||||
res += recv_data
|
res += recv_data
|
||||||
recv_size += len(recv_data)
|
recv_size += len(recv_data)
|
||||||
|
|
||||||
print(res.decode('gbk'))
|
print(res.decode('gbk'))
|
||||||
|
|
||||||
phone.close()
|
phone.close()
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
FTP上传下载文件的代码(简单版)
|
FTP上传下载文件的代码(简单版)
|
||||||
@@ -775,7 +849,6 @@ import socket
|
|||||||
import struct
|
import struct
|
||||||
import json
|
import json
|
||||||
sk = socket.socket()
|
sk = socket.socket()
|
||||||
## buffer = 4096 # 当双方的这个接收发送的大小比较大的时候,就像这个4096,就会丢数据,这个等我查一下再告诉大家,改小了就ok的,在linux上也是ok的。
|
|
||||||
buffer = 1024 #每次接收数据的大小
|
buffer = 1024 #每次接收数据的大小
|
||||||
sk.bind(('127.0.0.1',8090))
|
sk.bind(('127.0.0.1',8090))
|
||||||
sk.listen()
|
sk.listen()
|
||||||
@@ -794,9 +867,10 @@ with open(head['filename'],'wb') as f:
|
|||||||
f.write(content)
|
f.write(content)
|
||||||
filesize -= buffer
|
filesize -= buffer
|
||||||
else:
|
else:
|
||||||
content = conn.recv(buffer)
|
content = conn.recv(filesize)
|
||||||
f.write(content)
|
f.write(content)
|
||||||
break
|
break
|
||||||
|
print(head['filename'], "接收成功")
|
||||||
|
|
||||||
conn.close()
|
conn.close()
|
||||||
sk.close()
|
sk.close()
|
||||||
@@ -813,15 +887,14 @@ sk = socket.socket()
|
|||||||
sk.connect(('127.0.0.1',8090))
|
sk.connect(('127.0.0.1',8090))
|
||||||
buffer = 1024 #读取文件的时候,每次读取的大小
|
buffer = 1024 #读取文件的时候,每次读取的大小
|
||||||
head = {
|
head = {
|
||||||
'filepath':r'C:\Users\Aaron\Desktop\新建文件夹', #需要下载的文件路径,也就是文件所在的文件夹
|
'filepath':r'C:\Users\simid\Desktop', #需要下载的文件路径,也就是文件所在的文件夹
|
||||||
'filename':'config', #改成上面filepath下的一个文件
|
'filename':'KKRIEGER.EXE', #改成上面filepath下的一个文件
|
||||||
'filesize':None,
|
'filesize':None,
|
||||||
}
|
}
|
||||||
|
|
||||||
file_path = os.path.join(head['filepath'],head['filename'])
|
file_path = os.path.join(head['filepath'],head['filename'])
|
||||||
filesize = os.path.getsize(file_path)
|
filesize = os.path.getsize(file_path)
|
||||||
head['filesize'] = filesize
|
head['filesize'] = filesize
|
||||||
# json_head = json.dumps(head,ensure_ascii=False) #字典转换成字符串
|
|
||||||
json_head = json.dumps(head) #字典转换成字符串
|
json_head = json.dumps(head) #字典转换成字符串
|
||||||
bytes_head = json_head.encode('utf-8') #字符串转换成bytes类型
|
bytes_head = json_head.encode('utf-8') #字符串转换成bytes类型
|
||||||
print(json_head)
|
print(json_head)
|
||||||
|
Reference in New Issue
Block a user