1. 程式人生 > >day37 Pyhton 網路程式設計04

day37 Pyhton 網路程式設計04

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