日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

pythonsocket自定义协议_小渣渣学习笔记 python day28【tcp聊天 udp聊天 粘包 自定义协议 struct模块】...

發布時間:2025/3/15 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pythonsocket自定义协议_小渣渣学习笔记 python day28【tcp聊天 udp聊天 粘包 自定义协议 struct模块】... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

tcp 實現聊天功能

server端

import socket

sk = socket.socket()

sk.bind(('127.0.0.1',22000))

sk.listen()

while True: #同時連多個人

obj,addr = sk.accept() #三次握手在這里完成

while True:

msg = input('>>>')

if msg.upper() == 'Q':break

obj.send(msg.encode('utf-8'))

content = obj.recv(1024).decode('utf-8')

print(content)

obj.close()

sk.close()

client端

import socket

sk = socket.socket() #實例化socket對象

sk.connect(('127.0.0.1',22000)) #生成連接

while True:

content = sk.recv(1023).decode('utf-8') #接受內容

print(content) #打印內容

msg = input('>>>')

if msg.upper() == 'Q':break

sk.send(msg.encode('utf-8')) #發送內容

sk.close() #關閉

udp 實現聊天功能

server端

import socket

sk = socket.socket(type=socket.SOCK_DGRAM)

sk.bind(('127.0.0.1',22000))

while True:

msg,addr = sk.recvfrom(1204)

print(msg.decode('utf-8'))

msg = input('>>>')

if msg.upper()=='Q':break

sk.sendto(msg.encode('utf-8'),addr)

sk.close()

client端

import socket

sk = socket.socket(type=socket.SOCK_DGRAM) #實例化socket對象

while True:

msg = input('>>>')

if msg.upper()=='Q':break

sk.sendto(msg.encode('utf-8'),('127.0.0.1',22000))

msg,addr = sk.recvfrom(1111)

print(msg.decode('utf-8'))

sk.close() #關閉

粘包現象

import socket

sk = socket.socket()

sk.bind(('127.0.0.1',9001))

sk.listen()

conn,addr = sk.accept()

conn.send(b'aa') #分別發送aa 和 bb

conn.send(b'bb')

conn.close()

sk.close()

import socket

import time

sk = socket.socket()

sk.connect(('127.0.0.1',9001))

time.sleep(0.1) #sleep 0.1s

msg1 = sk.recv(1024)

print(msg1) #b'aabb' 本來aa 和bb 應該分別在msg1 和msg2 打印出來的,現在放在一起打印了,就因為前面有了一個sleep了0.1秒,這就是粘包現象

msg2 = sk.recv(1024)

print(msg2) #b''

sk.close()

#粘包現象(只發生在tcp協議中)

#發生在發送端,消息很短,放在緩存池中,操作系統固定間隔再發送

#發生在接收端,接受不及時

#只發生在tcp協議,因為tcp協議多條消息之間沒有邊界,并且還有一大堆優化算法

#tcp協議中為什么存在沒有邊界,

#udp協議 網絡最大帶寬限制 MTU = 1500字節

#tcp沒有上限,如果文件比較大,可以拆開

#解決粘包關鍵是設置邊界

#【作業】 socket 發送文件

#治療一下粘包

#server端

import socket

ipaddr = '127.0.0.1'

port = 10001

sk = socket.socket()

sk.bind((ipaddr,port))

sk.listen()

conn,addr = sk.accept()

msg1 = input('>>>').encode('utf-8') #輸入‘你是猴子請來的救兵么’并轉成bytes

msg2 = input('>>>').encode('utf-8') #輸入‘是的’

num = str(len(msg1)) #計算第一次輸入的字符串字節數,限制字節數為9999

print(num) #30 因為一個漢字utf-8 占3個字節,10個字

len1 = num.zfill(4) #補全數字到4位,client客戶端就要先接收4位

conn.send(len1.encode('utf-8'))

conn.send(msg1)

conn.send(msg2)

conn.close()

sk.close()

#client端

import socket

import time

ipaddr = '127.0.0.1'

port = 10001

sk = socket.socket()

sk.connect((ipaddr,port))

time.sleep(0.2)

len1 = int(sk.recv(4).decode('utf-8')) #先接收4位

msg1 = sk.recv(len1).decode('utf-8')

msg2 = sk.recv(1024).decode('utf-8')

print(msg1) #打印 ‘你是猴子請來的救兵么’

print(msg2) #打印‘是的’

sk.close()

#以上就是我自定義的協議,第一次發送最多9999字節的字符串

#下面學習一個新的模塊 struct

import struct

num1 = 129469649

num2 = 2342

num3 = 1

ret = struct.pack('i',num1) #i代表4個字節 b代表1個字節 H 和h 代表2個字節 d是8位

print(ret) #b'\xd1\x8c\xb7\x07' 4個字節

ret2 = struct.pack('i',num2)

print(ret2) #b'&\t\x00\x00' 4個字節

ret3 = struct.pack('i',num3)

print(ret3) #b'\x01\x00\x00\x00' 4個字節

#struct.pack() 可以把任意數字轉成4個字節

#還可以轉回來

print(struct.unpack('i',ret)) #(129469649,) 得到的是一個元組,第一個元素就是

print(struct.unpack('i',ret2)) # (2342,)

print(struct.unpack('i',ret3)) #(1,)

#那么上面的server端 自定義協議處,先發送字節就可以變更一下

#server端

import socket

import struct

ipaddr = '127.0.0.1'

port = 10001

sk = socket.socket()

sk.bind((ipaddr,port))

sk.listen()

conn,addr = sk.accept()

msg1 = input('>>>').encode('utf-8') #輸入‘你是猴子請來的救兵么’并轉成bytes

msg2 = input('>>>').encode('utf-8') #輸入‘是的’

# num = str(len(msg1)) #計算第一次輸入的字符串字節數,限制字節數為9999

# len1 = num.zfill(4) #補全數字到4位,client客戶端就要先接收4位

blen = struct.pack('i',len(msg1))

# msg1是轉成bytes后的類型,主要是先發到對方msg1的長度len(msg1)比如等于233,client端要先接收到233

# 然后根據233,recv(233)接收233個字節數的字節,再展示出來

# 我不能send一個len(msg1)這樣的int數字過去,但是可以把len(msg1)用struct.pack()轉成byte類型傳過去,

# 過去之后再struct.unpack(),再轉成int類型len1,送給recv(len1)

conn.send(blen) # 這里blen已經是bytes類型,就不用encode了

conn.send(msg1)

conn.send(msg2)

conn.close()

sk.close()

#client端

import socket

import struct

import time

ipaddr = '127.0.0.1'

port = 10001

sk = socket.socket()

sk.connect((ipaddr,port))

len1 = struct.unpack('i',sk.recv(4))[0]

#先接收4位byte類型,sk.recv(4) ,完了以后再把他struct.unpack()一下,得到是元組,取第一個元素[0],就是首先發過來的長度

#struct 可以一句話搞定自定義發送協議

msg1 = sk.recv(len1).decode('utf-8')

msg2 = sk.recv(1024).decode('utf-8')

print(msg1) #打印 ‘你是猴子請來的救兵么’

print(msg2) #打印‘是的’

sk.close()

#后續為了防止粘包,豈不是每次都要先發送長度,再根據長度接收內容?

#【練習】

#1、基于tcp協議的登陸認證:客戶端輸入用戶名密碼,發送到服務器端,服務器端認證,發送結果到客戶端

#2、基于udp協議的多人聊天,自動識別用戶 不能用ip和port

#3、基于tcp協議完成一個文件的上傳,先處理小文件,在處理大文件

#4、選課系統

#總結

#tcp協議

#socket 模塊引用

#sk的創建

#conn的創建

#接收多個客戶端的請求,while True的位置

#怎么退出

#udp協議

#語法 socket創建的區別,加參數type

#涉及的發送和接收新方法 sendto recvfrom

#和tcp協議區別

#聊天程序

#粘包現象

#tcp協議的特點?三次握手連接,四次揮手斷開

#什么是粘包,發送端發送數據頻率高,下層來不及發送,固定時間間隔統一發送,接收端來不及接收

#怎么處理?先發送長度,根據長度接收內容

#自定義協議

#struct模塊應用

#不用struct能不能自定義協議?根據發送字節長度int用zfill方法換算成固定字節長度的數值,傳到接收端,接收端根據數值轉成int,再根據int接收內容

總結

以上是生活随笔為你收集整理的pythonsocket自定义协议_小渣渣学习笔记 python day28【tcp聊天 udp聊天 粘包 自定义协议 struct模块】...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。