网络编程2
socket套接字
socket套接字简介
套接字就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。socket套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议栈进行交互的接口。
socket模块
cs架构的软件无论是在编写环节还是运行环节都应该先考虑服务端,有了服务端运行才能够给客户端提供服务
# 服务端
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8088))
server.listen(5)
sock, addr = server.accept()
print(sock, addr)
data = sock.recv(1024).decode('utf8')
print(f'收到的消息:{data}')
msg = input('需要发送的信息>>>:').strip()
server.send(msg.encode('utf8'))
sock.close()
server.close()
# 客户端
import socket
client = socket.socket()
client.connect(('127.0.0.1', 8088))
msg = input('需要发送的信息>>>:').strip()
client.send(msg.encode('utf8'))
data = client.recv(1024)
print(data.decode('utf8'))
client.close()
通信循环
- 先解决消息固定的问题
利用input获取用户输入 - 再解决通信循环的问题
将双方用于数据交互的代码循环起来
# 服务端
import socket
server = socket.socket()
server.bind(('127.0.0.1', 9988))
server.listen(5)
while True:
sock, addr = server.accept()
print(sock, addr)
while True:
try:
data = sock.recv(1024)
if len(data) == 0:
continue
print(data.decode('utf8'))
msg = input('请输入回复消息>>>:').strip()
if not msg:
msg = '服务器正忙'
sock.send(msg.encode('utf8'))
except Exception:
break
# 客户端
import socket
client = socket.socket()
client.connect(('127.0.0.1', 9988))
while True:
msg = input('需要发送的信息>>>:').strip()
client.send(msg.encode('utf8'))
data = client.recv(1024)
print(data.decode('utf8'))
client.close()
解决黏包问题
上传和下载视频
# 上传端
import socket
import os
import struct
import json
server = socket.socket()
from socket import SOL_SOCKET, SO_REUSEADDR
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
server.bind(('127.0.0.1', 9412))
server.listen(5)
conn, addr = server.accept()
data_dict = {
'file_name': None,
'file_desc': None,
'file_size': None
}
file_name = input('请输入文件名称>>>:').strip()
file_desc = input('请简述文件信息>>>:').strip()
file_path = input('请输入文件地址>>>:').strip()
file_size = os.path.getsize(file_path)
data_dict['file_name'] = file_name
data_dict['file_desc'] = file_desc
data_dict['file_size'] = file_size
# 1.打包字典
dict_json_str = json.dumps(data_dict)
dict_bytes = dict_json_str.encode('utf8')
dict_package_header = struct.pack('i', len(dict_bytes))
# 2.发送报头
conn.send(dict_package_header)
# 3.发送字典
conn.send(dict_bytes)
# 4.发送真实数据
with open(r'%s' % file_path, 'rb') as f:
for line in f:
conn.send(line)
# 下载端
import os.path
import socket
import struct
import json
client = socket.socket()
client.connect(('127.0.0.1', 9412))
# 1.接收的字典的报头
dict_header_len = client.recv(4)
# 2.解析出字典的真实长度
dict_real_len = struct.unpack('i', dict_header_len)[0]
# 3.接收字典数据
dict_data_bytes = client.recv(dict_real_len)
dict_data = json.loads(dict_data_bytes)
print(dict_data)
new_file_path = input('请输入文件保存地址>>>:').strip()
if not os.path.exists(new_file_path):
os.mkdir(new_file_path)
down_path = os.path.join(new_file_path, dict_data.get('file_name'))
# 4.循环接收文件数据,防止文件过大内存溢出
recv_size = 0
with open(down_path, 'wb') as f:
while recv_size < dict_data.get('file_size'):
data = client.recv(1024)
recv_size += len(data)
f.write(data)