# tcp协议和udp协议的选择问题 # tcp # 大量的连续的数据 传递文件\发送邮件 # 文件的传递 # 下载电影 # udp # 短消息类 社交软件 # qq 微信 # 在线播放视频 快会丢帧 # 黏包 # 黏包现象 # 连续send,对应连续的recv # 在tcp连接中 消息之间无边界 # 黏包现象的解决 # send(b'hello') 5 1个字节 # send(b'world') # send(b'hello'*10) 50 2个字节 # send(b'world') # send(b'hello'*100) 500 3个字节 # send(b'world')
# 数据类型 : int str bytes # 编码 : ascii utf-8 gbk
# 01 # 二进制 --> 十进制 # 计算机习惯用 人用
# 如果像字典一样给每一个文字字母和数字都添加一个编号,就可以用数字表示其他元素了 # 数字 字母 常用的符号 阿拉伯文 第一批我们说的ascii 0-255
# print(bin(65)) # print(bin(250)) # 11111010 # print(chr(250)) # chr接受一个ascii码,返回一个对应的字符 # Aú 01000001 11111010 # 字节 8位是一个字节
# 1字节 = 8位2进制数 # byte bit # bytes
# ascii # 各自国家的标准码(没有统一) # unicode 万国码 浪费空间 # utf-8 节省空间的 万国码
# 文件存储在硬盘上 : 010101010 # 二进制 -8位一读-> 字节 # bytes --> str字符串 # 你要确认bytes类型到底是什么编码的 # bytes.decode('utf-8')
# str --> bytes # str.encode('utf-8') # utf-8编码之后的字节 '中' # str.encode('其他编码') # utf-8编码之后的字节 'yo'
# 1.所有编码与编码之间的关系 : ascii码 各自国家的编码(gbk gb2312) unicode(万国码) utf-8(存储了所有国家中的文字) # 2.你读出来的字符 --> 字节 # 字符串数据类型中的一个元素 就是一个字符 如果是中文字符串,每一个"字"都是一个字符 # 如果是英文字符串,每一个"字母"都是一个字符 # 每一个字符都可以转换成对应的 字节 bytes # bytes是最接近二进制的内容
# 3.能在文件中存储的\在网络上传输的都是二进制 # 但是计算机中我们传递数据不需要程序员自己去把要传递的内容转成二进制了 # 你只需要把内容转换成bytes(字节)就可以了
# 4.所以如果是utf-8编码的化 对于数字\字母\符号你的转换永远遵循ascii,且只占1个字节
# 5.并且在网络上传输的由于都是字节,所以我们所计算的传输长度,也是字节的长度而不是字符的长度 # recv(1024) 1024代表字节 # 'hello,中国' # 8个字符 = 6个字节 + 3个字节*2 = 6+6 = 12个字节 # 所以我们send的时候send的是字节串,我们接收的时候也接受的是字节串
# 6.你不能在网络上传递int类型,只能传bytes # int --> str --> bytes # 5 '5' b'5'
# os模块 # 1.os.path.join('绝对路径','文件名') # 2.os.path.split(E:\s17\day33\1.内容回顾.py) 分割 :(E:\s17\day33,1.内容回顾.py) # 3.os.path.dirname('E:\s17\day33') 获取路径的上一级目录'E:\s17' # 4.os.path.basename('E:\s17\day33') 获取路径的最后一层名字day33 # 5.os.rename # 6.os.remove # 7.os.makedirs('E:\s17\day33\new\new2') 创建一个新目录 # os.mkdir('新的路径') # 8.os.path.isfile('E:\s17\day33\1.内容回顾.py') 判断E:\s17\day33\1.内容回顾.py是不是文件 # 9.os.path.getsize('E:\s17\day33\1.内容回顾.py') 获取1.内容回顾.py文件的字节大小 # 10.os.listdir('E:\s17\day33') 显示'E:\s17\day33'路径下的所有文件和文件夹
# struct模块是干什么的??? # import struct # 只做一件事儿 能够将数字转换成固定4字节的bytes # ret3 = struct.pack('i',500) # 帮助你 数字 -(固定4个字节)-> bytes # print(ret3,len(ret3)) # ret2 = struct.pack('i',50) # 帮助你 数字 -(固定4个字节)-> bytes # print(ret2,len(ret2)) # ret = struct.pack('i',5) # 帮助你 数字 -(固定4个字节)-> bytes # print(ret,len(ret))
# res = struct.unpack('i',ret) # print(res) # res2 = struct.unpack('i',ret2) # print(res2) # res3 = struct.unpack('i',ret3) # print(res3)
# 编码 # os模块 # 网络基础的逻辑 # tcp/udp协议 # 黏包 # socketserver # 校验客户端是否合法 # 文件的上传 # 本周大作业 # ftp需求
校验客户端是否合法
import os import socket import hmac def check_conn(conn): secret_key = b'alex_sb' rand_code = os.urandom(32) conn.send(rand_code) obj = hmac.new(secret_key,rand_code) byte_ret = obj.digest() byte_msg = conn.recv(1024) if byte_ret == byte_msg: return True else: return False sk = socket.socket() sk.bind(('127.0.0.1',9000)) sk.listen() conn,addr = sk.accept() if check_conn(conn): '''写你本身要写的代码''' conn.send('你是合法的连接'.encode()) msg = conn.recv(1024) print(msg.decode()) conn.close() # 只有程序认可的用户才能使用我的server端 # 1.登陆 # 2.随意的一个server # 只要是我写的client端都可以使用我的server # 公司通用业务 # 在建立和client端的连接之后 # 有一种检测这个客户端是否合法的机制 # 如果合法 再继续通讯 # 如果不合法 直接关闭
import socket import hmac def check_conn(sk): secret_key = b'alex_sb' rand_code = sk.recv(32) obj = hmac.new(secret_key,rand_code) byte_ret = obj.digest() sk.send(byte_ret) sk = socket.socket() sk.connect(('127.0.0.1',9000)) check_conn(sk) # 以下部分你可以自由发挥 print(sk.recv(1024).decode()) sk.send('那么愉快的开始沟通吧'.encode('utf-8')) sk.close()
socketserver
import struct import socketserver class Myserver(socketserver.BaseRequestHandler): def handle(self): conn = self.request msg = '你好'.encode('utf-8')*100 int_num = len(msg) byte_num = struct.pack('i',int_num) conn.send(byte_num) # 4bytes conn.send(msg) conn.send(b'world') server = socketserver.ThreadingTCPServer(('127.0.0.1',9000),Myserver) server.serve_forever()
import time,struct import socket sk = socket.socket() sk.connect(('127.0.0.1',9000)) time.sleep(0.5) num = struct.unpack('i',sk.recv(4)) print(sk.recv(num[0]).decode('utf-8')) print(sk.recv(1024))