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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

day 29

發布時間:2023/12/18 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 day 29 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

半連接與粘包問題

半連接數

1、定義:

  三次握手沒有完成的稱之為半連接數

2、產生半連接的原因:

  1)惡意客戶端故意不返回第三次握手信息,服務器就處于time_wait狀態

      洪水攻擊用的就是這種原理

  2)服務器沒有時間處理你的握手請求

3、最大半連接數

  在socket語法中listen()函數的括號中指定的就是最大半連接數

  最大半連接數指的是同一時間接收請求的最大數目,超過的請求會被直接拒絕

粘包問題

粘包問題只存在于TCP協議中,TCP協議又稱為流式協議,數據之間是沒有分隔的(只能用數據的長度來分隔他們)

1、粘包的定義

  如果一次讀取指定緩存區的內容大于或者小于真實數據的大小,就被定義被粘包

2、粘包產生的原因

  發送端和接收端都會造成數據的粘包問題

  --發送端

    1)發送的數據小,并且時間間隔短時,tcp會根據negal優化算法把這兩個數據一起發送,會粘

  --接收端

    1)接收端一次性讀取了兩次的數據內容,會粘

    2)接收端一次沒有把數據接收完整,剩余內容和下次發送的也會粘在一起

3、粘包的解決方案

  無論時哪種情況,其根本的原因都在于接收端不知道應該接收多少數據,所以解決的方案就是先把數據長度發給接收端

  --發送端

    1)使用struct將真實數據的長度轉換成固定的字節數據

    2)發送長度數據

    3)發送真實數據

import socket import struct client = socket.socket() client.connect(('127.0.0.1',8080))while True:data = '巴拉巴拉一大堆數據'.encode('utf-8')data_len = struct.pack('q',len(data)) # 把數據長度轉成固定字節數client.send(data_len) # 先發送固定字節數 'q'模式的字節數是8client.send(data) # 再發送真實的數據

  --接收端

    1)先收長度數據? 字節數固定

    2)再收真實數據 ,真實可能很長,需要循環接收

import socket import struct server = socket.socket() server.bind(('127.0.0.1',8080)) server.listen()while True:client,addr = server.accept()while True:data_len_bytes = client.recv(8) # 先接收傳過來的數據長度信息的固定字節'q'模式是8if not data_len_bytes:breakdata_len = struct.unpack('q',data_len_bytes)[0] # 把接收到的二進制轉成數據的長度,返回一個元組,取0號位data = client.recv(data_len) # 再根據長度來接收數據(循環接收請看前面)

?

自定義報頭

1、需要原因

  有時候我們除了需要把數據的長度告訴接收方,還需要把一些其他信息也告訴接收方,例如我們下載文件,

  服務器就需要把文件名也給我們傳過來,這樣就需要我們自定義報頭

2、報頭形式

  當我們想把數據的其他信息傳給對面的時候,字典是我們最好的選擇

  對面和你的平臺可能不一樣,這樣我們就需要json格式來傳輸數據,所以報頭的本質就是json數據

  想把json數據發過去,又需要先把json數據的長度發過去,真實數據的信息都保存在json數據中

3、有了報頭之后的發送流程

  --發送端

    1)發送報頭長度

    2)發送報頭數據? ?其中包含了真實文件的長度和其他的任意額外信息

    3)發送真實文件內容

import socket,struct,json client = socket.socket() client.connect(('127.0.0.1',8080))while True:data = "我是一個很大的文件,并且對面要根據我的名字保存"# 先寫出報頭信息head_info = {"name":"xxx","size":10000}# 把報頭信息轉換成json格式json_head = json.dumps(head_info)# 把json格式的報頭信息的二進制長度轉換成固定字節json_head_lens = struct.pack('q',len(json_head.encode('utf-8')))# 發送固定字節,讓多方知道該以多少長度接收報頭信息client.send(json_head_lens)# 發送報頭信息,里面包含接下來要發送的真實數據的大小以及名字等等client.send(json_head.encode('utf-8'))# 發送真實數據client.send(data.encode('utf-8'))

  --接收端

    1)接收報頭長度

    2)接收報頭信息

    3)接收文件內容

import socket import struct import json server = socket.socket() server.bind(('127.0.0.1',8080)) server.listen()while True:client,addr = server.accept()while True:head_len_bytes = client.recv(8)# 先把固定字節數的報頭長度接收過來if not head_len_bytes:breakhead_len = struct.unpack('q',head_len_bytes)[0]# 轉換成報頭的長度數據json_str = client.recv(head_len).decode('utf-8')# 接收報頭的信息,傳過來的是json格式head_info = json.loads(json_str)# 轉成字典格式,方便取值#head_info = {"name":"xxx","size":10000}file_size = head_info.get("size")# 從字典中取出真實文件的大小,根據大小取值,循環取值請看之前的data = client.recv(file_size)

轉載于:https://www.cnblogs.com/huikejie/p/10966090.html

總結

以上是生活随笔為你收集整理的day 29的全部內容,希望文章能夠幫你解決所遇到的問題。

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