目录
- 一、网络编程大体图
- 二、TCP协议
- 1.三次握手,四次挥手图
- 2.tcp代码
- 1.简单版
- 2.电影上传
- 3.json补充,序列化类
- 4.subprocess补充
- 三、UDP的使用
- 1.简介
- 2.使用基本代码
- 2.1简易版qq
- 四、UDP和TCP的区别
一、网络编程大体图
计算机与计算机之间的通信:
二、TCP协议
TCP协议又叫:流失协议、可靠协议
1.TCP协议像流水一样一直发送,一直接收
2.TCP协议可靠的原因:有反馈机制(发送一句,回复一句才会发送下一句)
洪水攻击:同一时间发送给服务器大量请求
1.三次握手,四次挥手图
2.tcp代码
1.简单版
服务端:
import socket
server = socket.socket() # 生成对象
server.bind(('127.0.0.1', 8080)) # 绑定IP和端口 (自己的)
server.listen(5) # 半连接池,允许等待数
conn, addr = server.accept() # 等待接听
# conn:地址 addr:端口号(随机分配)
while True:
data = conn.recv(1024) # 接收
print(data) # 打印接收的内容
# 判断如果接收的是空,就跳出循环
if len(data) == 0:
break
conn.send(data.lower()) # 发送反馈内容
客户端:
import socket
client = socket.socket() # 生成对象
client.connect(('127.0.0.1', 8080)) # 拨号,对方IP和端口
while True:
msg = input('请输出 >>>:').strip().encode('utf-8') # 转二进制
if len(msg) == 0:
continue
client.send(msg) # 发送
data = client.recv(1024) # 接收反馈内容
print(data)
2.电影上传
1.打包,固定长度模块struct
注意:一般用'i'模式,固定4个字节 长度,q模式最大8个字节长度
import struct
"""
利用struct给
"""
res1 = 'asdfkjhksdhfksadhfkkshfasjdfklasddfjkl'
print('开始的', len(res1))
res2 = struct.pack('i', len(res1))
print('压缩的', len(res2))
res3 = struct.unpack('i', res2)[0]
print('解压的', res3)
客户端:
import os
import socket
import struct
import json
move = socket.socket() # 生成对象
move.connect(('127.0.0.1', 8080)) # 写服务端的IP,port
while True:
# 1.拼接文件路径
MOVE_PATH = r'E:\学习视频\python老男孩\对象\day20\视频'
move_list = os.listdir(MOVE_PATH)
# 循环打印
for i in move_list:
print(move_list.index(i)+1, i)
# 用户选择
choice = input('请选择你要上传的电影>>>:')
# 判断输入是否为数字
if choice.isdigit():
# 转成int型
choice = int(choice)-1
# 判断是否在范围内
if choice in range(0, len(move_list)):
# 拿到用户选择的文件
move_choice = move_list[choice]
# 拼接文件路径
move_path = os.path.join(MOVE_PATH, move_choice)
# 拿到文件大小
move_size = os.path.getsize(move_path)
# 定义字典容器,数据放到字典中
move_dict = {'name': '陪你到老.mp4', 'size': move_size}
# 转成json格式和转成二进制格式的字典
json_dict = json.dumps(move_dict).encode('utf-8')
# 制作字典报头
hander_dict = struct.pack('i', len(json_dict))
# 发送报头
move.send(hander_dict)
# 发送字典
move.send(json_dict)
# 发送文件
with open(move_path, 'rb')as f:
for i in f:
move.send(i)
else:
print('你选的不在范围内')
else:
print('请输入数字')
服务端:
import os
import socket
import json
import struct
server = socket.socket() # 生成对象
server.bind(('127.0.0.1', 8080)) # 绑定IP,port
server.listen(5) # 半连接池
while True:
data, addr = server.accept() # 接受连接
# print(data, addr)
while True:
try:
# 接收字典报头
dict_hand = data.recv(4)
# 解析字典报头,拿到字典长度
dict_len = struct.unpack('i', dict_hand)[0] # 接收了一个元组,索引0的位置就是字典长度
# 接收字典长度,就是接收字典
dict_json = data.recv(dict_len)
# 解开json,解码二进制
dict = json.loads(dict_json.decode('utf-8'))
# 从字典中获取文件的大小长度
move_size = dict.get('size')
# 循环接收,并写入文件
accept_size = 0
# print(dict.get('name'))
with open(dict.get('name'), 'wb')as f:
while accept_size < move_size:
accept = data.recv(1024)
f.write(accept) # 写入文件
accept_size += len(accept)
print('上传成功')
except ConnectionResetError as f:
print(f)
break
data.close()
3.json补充,序列化类
from datetime import *
import json
"""序列化类.先转换成字符串型,才能序列化"""
# 1.手动转化成字符串型
b = str(datetime.today())
c = str(date.today())
a = {'1':b,'2':c}
# print(json.dumps(a))
d = str(datetime.today().strftime('%Y-%m-%d'))
# print(d)
e = type(datetime.today())
print(e)
# 2.定义一个继承json的新的类
class MyJson(json.JSONEncoder):
def default(self, o):
if isinstance(o,datetime):
return o.strftime('%Y-%m-%d %X')
elif isinstance(o,date):
return o.strftime('%Y-%m-%d')
else:
return super().default(self,o)
res = json.dumps(a)
print(res)
4.subprocess补充
import subprocess
cmd = input('输入命令>>>:')
obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
print(obj.stdout.read().decode('gbk')) # 正确命令返回结果
print(obj.stderr.read().decode('gbk')) # 错误命令返回结果
# subprocess获取到的数据 拿完就没有了 不能重复拿
三、UDP的使用
1.简介
udp协议又叫:
1.数据报协议(自带报头)
2.没有双向通道
3.也没有半连接池
发送数据就类似发短信,给指定的IP,port发送,不用管对方有没有收到
缺点:容易数据丢失,不安全
优点:速度快
2.使用基本代码
服务端:
import socket
server = socket.socket(type=socket.SOCK_DGRAM) # UDP协议
server.bind(('127.0.0.1', 8080)) # 绑定自己的地址端口
while True:
data, addr = server.recvfrom(1024) # 接收
print('接收到数据:', data)
print('地址:', addr)
server.sendto(data.upper(), addr) # 发送
客户端:
import socket
client = socket.socket(type=socket.SOCK_DGRAM)
server = ('127.0.0.1', 8080) # 要发送的地址端口
while True:
client.sendto(b'hello', server) # 发送
data, addr = client.recvfrom(1024) # 接收
print(data) # 打印
2.1简易版qq
服务端:
import socket
phone = socket.socket(type=socket.SOCK_DGRAM) # 1.建立对象
addres = ('127.0.0.1', 8080)
while True:
send = input('请输入要发送的内容>>>:').encode('utf-8')
phone.sendto(send, addres) # 2.发送内容,填写地址
data, addr = phone.recvfrom(1024) # 3.接收
print('收到内容:', data.decode('utf-8')) # 4.接收转码
客户端:
import socket
server = socket.socket(type=socket.SOCK_DGRAM) # 1.建立对象
server.bind(('127.0.0.1', 8080)) # 2.绑定地址
while True:
data, addr = server.recvfrom(1024) # 3.接收
print('收到的内容:', data.decode('utf-8')) # 4.打印,解码
print('对方地址:', addr) # 打印,解码
msg = input('请输入你要回复的内容>>>:').encode('utf-8')
server.sendto(msg, addr) # 5.回复发送
四、UDP和TCP的区别
UDP:类似发短信(只管往某个电话发短信,不管对方有没有看)
1.允许发空(自带报头)
2.不会粘包(自带报头)
3.UDP支持并发
4.UDP服务协议不安全(没有三次握手)
5.UDP速度更快
TCP:类似打电话(有人接听,有人回复)
1.不允许发空(没有报头)
2.会粘包(没有报头)
3.安全系数高(有三次握手)