recv原理、高階版黏包解決方案、基于UDP的socket通信

recv原理、高階版黏包解決方案、基于UDP的socket通信

recv原理

源碼解釋:
Receive up to buffersize bytes from the socket.
接收來自socket緩沖區的字節數據,
For the optional flags argument, see the Unix manual.
對于這些設置的參數,可以查看Unix手冊。
When no data is available, block untilat least one byte is available or until the remote end is closed.
當緩沖區沒有數據可取時,recv會一直處于阻塞狀態,直到緩沖區至少有一個字節數據可取,或者遠程端關閉。
When the remote end is closed and all data is read, return the empty string.
關閉遠程端并讀取所有數據后,返回空字符串。
# 1,驗證服務端緩沖區數據沒有取完,又執行了recv執行,recv會繼續取值。
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
phone.send('hello'.encode('utf-8'))
phone.close()# 2,驗證服務端緩沖區取完了,又執行了recv執行,此時客戶端20秒內不關閉的前提下,recv處于阻塞狀態。
import socket
import time
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
phone.send('hello'.encode('utf-8'))
time.sleep(20)phone.close()# 3,驗證服務端緩沖區取完了,又執行了recv執行,此時客戶端處于關閉狀態,則recv會取到空字符串。
import socket
import time
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
phone.send('hello'.encode('utf-8'))
phone.close()
# 1,驗證服務端緩沖區數據沒有取完,又執行了recv執行,recv會繼續取值。import socketphone =socket.socket(socket.AF_INET,socket.SOCK_STREAM)phone.bind(('127.0.0.1',8080))phone.listen(5)conn, client_addr = phone.accept()
from_client_data1 = conn.recv(2)
print(from_client_data1)
from_client_data2 = conn.recv(2)
print(from_client_data2)
from_client_data3 = conn.recv(1)
print(from_client_data3)
conn.close()
phone.close()# 2,驗證服務端緩沖區取完了,又執行了recv執行,此時客戶端20秒內不關閉的前提下,recv處于阻塞狀態。import socketphone =socket.socket(socket.AF_INET,socket.SOCK_STREAM)phone.bind(('127.0.0.1',8080))phone.listen(5)conn, client_addr = phone.accept()
from_client_data = conn.recv(1024)
print(from_client_data)
print(111)
conn.recv(1024) # 此時程序阻塞20秒左右,因為緩沖區的數據取完了,并且20秒內,客戶端沒有關閉。
print(222)conn.close()
phone.close()# 3 驗證服務端緩沖區取完了,又執行了recv執行,此時客戶端處于關閉狀態,則recv會取到空字符串。import socketphone =socket.socket(socket.AF_INET,socket.SOCK_STREAM)phone.bind(('127.0.0.1',8080))phone.listen(5)conn, client_addr = phone.accept()
from_client_data1 = conn.recv(1024)
print(from_client_data1)
from_client_data2 = conn.recv(1024)
print(from_client_data2)
from_client_data3 = conn.recv(1024)
print(from_client_data3)
conn.close()
phone.close()# recv空字符串: 對方客戶端關閉了,且服務端的緩沖區沒有數據了,我再recv取到空bytes.

高階版黏包解決方案

服務端:

import socket
import subprocess
import struct
import jsonphone = socket.socket()
phone.bind(('127.0.0.1',8897))phone.listen(3)
print("等待接入")
while 1:conn, addr = phone.accept()print(conn, addr)try:while 1:from_client_data = conn.recv(1024)if from_client_data.decode('utf-8').upper() == 'Q':print('對方中斷鏈接')breakobj = subprocess.Popen(from_client_data.decode('utf-8'),shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,)to_client_data = obj.stdout.read() + obj.stderr.read()total_size = len(to_client_data)dic = {'filename':'text1','MD5':120045318563413485631,'total_size':total_size}head1 = json.dumps(dic).encode('utf-8')len_head1 = len(head1)head_bytes = struct.pack('i',len_head1)conn.send(head_bytes)conn.send(head1)conn.send(to_client_data)except ConnectionError:print('對方中斷網絡鏈接')breakconn.close()
phone.close()

客戶端:

import socket
import struct
import json
phone = socket.socket()phone.connect(('127.0.0.1',8897))
while 1:to_server_data = input('請輸入內容')phone.send(to_server_data.encode('utf-8'))if to_server_data.upper() == "Q":print('主動退出')breakif not to_server_data.strip():continuehead = phone.recv(4)num = struct.unpack('i',head)[0]dic_head = phone.recv(num).decode('utf-8')dic = json.loads(dic_head)s = b''while len(s) < dic['total_size']:from_server_data = phone.recv(1024)s += from_server_dataprint(s.decode('gbk'))
phone.close()

基于UDP的socket通信

服務端:

import socket
udp_sk = socket.socket(type=socket.SOCK_DGRAM)   #創建一個服務器的套接字
udp_sk.bind(('127.0.0.1',9000))        #綁定服務器套接字
msg,addr = udp_sk.recvfrom(1024)
print(msg)
udp_sk.sendto(b'hi',addr)                 # 對話(接收與發送)
udp_sk.close()                         # 關閉服務器套接字

客戶端:

import socket
ip_port=('127.0.0.1',9000)
udp_sk=socket.socket(type=socket.SOCK_DGRAM)
udp_sk.sendto(b'hello',ip_port)
back_msg,addr=udp_sk.recvfrom(1024)
print(back_msg.decode('utf-8'),addr)

轉載于:https://www.cnblogs.com/lifangzheng/p/11366039.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/247129.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/247129.shtml
英文地址,請注明出處:http://en.pswp.cn/news/247129.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

iOS中下載大型文件的原理解析二

在iOS中下載大型文件&#xff0c;需要使用NSURLConnection 的代理方法&#xff1a; (void)touchesBegan:(NSSet)touches withEvent:(UIEvent *)event { NSURL *url [NSURL URLWithString:”http://d.3987.com/fengj_141112/007.jpg“]; NSURLRequest *request [NSURLReque…

ASP.NET Core Web 應用程序開發期間部署到IIS自定義主機域名并附加到進程調試

想必大家之前在進行ASP.NET Web 應用程序開發期間都有用到過將我們的網站部署到IIS自定義主機域名并附加到進程進行調試。 那我們的ASP.NET Core Web 應用程序又是如何部署到我們的IIS上面進行調試的呢&#xff0c;接下來我們來簡單介紹下&#xff1a; 一、安裝IIS所需的Host擴…

iOS下載大型文件原理解析三

在下載大型文件過程中是可以取消下載的 - (IBAction)download:(UIButton *)sender { // 狀態取反 sender.selected !sender.isSelected; // 斷點續傳 // 斷點下載if (sender.selected) { // 繼續&#xff08;開始&#xff09;下載// 1.URLNSURL *url [NSURL URLWithStrin…

HTML文件上傳與下載

文件下載 傳統的文件下載有兩種方法&#xff1a; 使用<a/>標簽&#xff0c;href屬性直接連接到服務器的文件路徑window.location.href"url"這兩種方法效果一樣。但有個很大的問題&#xff0c;如果下載出現異常&#xff08;連接路徑失效、文件不存在、網絡問題等…

NSURLSession的應用

iOS7以后發布了NSURLSession用來替換NSURLConnection&#xff0c;NSURLSession使用方式有以下兩種&#xff1a; 1.block方式 &#xff08;1&#xff09;創建的步驟 獲取單例會話對象 創建URL對象 隱含創建request 創建NSURLSessionDataTask // 1.獲取會話對象 NSURLSess…

ASP.NET Core Web 應用程序系列(一)- 使用ASP.NET Core內置的IoC容器DI進行批量依賴注入(MVC當中應用)...

在正式進入主題之前我們來看下幾個概念&#xff1a; 一、依賴倒置 依賴倒置是編程五大原則之一&#xff0c;即&#xff1a; 1、上層模塊不應該依賴于下層模塊&#xff0c;它們共同依賴于一個抽象。 2、抽象不能依賴于具體&#xff0c;具體依賴于抽象。 其中上層就是指使用者&am…

iOS中XML解析

iOS中XML解析分為兩種實現方式&#xff1a;SAX與DOM SAX方式&#xff1a;主要是事件驅動的解析方式&#xff0c;是逐行讀取XML數據&#xff0c;不斷回調代理&#xff0c;告訴代理當前解析的元素開始或者結束。 DOM解析方式&#xff1a;是講整個XML數據全部讀入內存&#xff0…

蘋果電腦基本設置+Linux 命令+Android 實戰集錦

本文微信公眾號「AndroidTraveler」首發。 背景 大多數應屆畢業生在大學期間使用的比較多的是 windows 電腦&#xff0c;因此初入職場如果拿到一臺蘋果電腦&#xff0c;可能一時間不能夠很快的上手。基于此&#xff0c;這邊出了系列視頻&#xff0c;通過實際的演示讓沒使用過蘋…

iOS中POST請求

iOS中POST請求的發送需要使用NSMutableURLRequest可以設置URL request的頭字段&#xff0c;比如超時時間&#xff0c;請求類型&#xff1a;GET POST等一些關鍵頭字段&#xff1a; - (IBAction)login { // 1.用戶名 NSString *usernameText self.username.text; if (userna…

發送JSON數據給服務器

需要將JSON格式的數據傳送給服務器&#xff0c;注意需要設置&#xff1a; [request setValue:”application/json” forHTTPHeaderField:”Content-Type”]; Content-Type類型為&#xff1a;application/json // 1.URL NSURL *url [NSURL URLWithString:"http://localh…

Mac中AndroidStudio沒有找到Plugins的問題

我們在windows中都可以正常找到plugins 但是在Mac上AndroidStudio里 setting打開卻沒有plugins 正準備在Mac上搞一下flutter呢 我感覺智商受到了侮辱&#xff01; 這里其實是mac版本給我開了個玩笑 你可以按快捷鍵&#xff0c;你就可以找到 快捷鍵 command ‘,’ 沒錯就是comm…

進程和操作系統概述

進程和操作系統概述 進程的基礎 程序和進程&#xff1a; 程序是一對靜態的代碼文件 進程是一個正在運行著的程序&#xff0c;抽象概念 進程由操作系統操控調用交于CPU運行 操作系統 1.管理控制協調計算機硬件和軟件的關系 2.操作系統的作用&#xff1f; ? 第一個作用&#xff…

iOS手勢操作簡介(一)

iOS中能夠響應手勢操作的類必須要繼承自UIResponder&#xff0c;才能夠處理手勢響應操作。 默認繼承了UIResponder的類有&#xff1a;UIApplication UIViewController UIView都繼承自UIResponder. UIView是UIResponder的子類&#xff0c;可以實現下列4個方法處理不同的觸摸事…

iOS開發中手勢處理簡介(二)

iOS中手勢操作事件的產生于傳遞 發生觸摸事件后&#xff0c;系統會將該事件加入到一個由UIApplication管理的事件隊列中 UIApplication會從事件隊列中取出最前面的事件&#xff0c;并將事件分發下去以便處理&#xff0c;通常&#xff0c;先發送事件給應用程序的主窗口&#x…

對前端Jenkins自動化部署的研究

1. 安裝 安裝 Nginx 1.1去官網下直接下載&#xff0c;解壓縮 start nginx就可以使了&#xff0c;常用命令&#xff1a; start nginx # 啟動 nginx -s reload # 修改配置后重新加載生效 nginx -s reopen # 重新打開日志文件 nginx -t # 配置文件檢測是否正確 1.2 安裝Jenkins…

python超神之路:Python3 列表list合并的4種方法

Python3 列表list合并的4種方法 方法1: 直接使用""號合并列表 aList [1,2,3] bList [www, pythontab.com] cList aList bList dList bList aList print(cList) print(dList) # 結果&#xff1a; [1, 2, 3, www, pythontab.com] [www, pythontab.com, 1, 2, 3] …

iOS手勢操作簡介(三)

監聽觸摸事件的做法 如果想監聽一個view上面的觸摸事件&#xff0c;之前的做法是 自定義一個view 實現view的touches方法&#xff0c;在方法內部實現具體處理代碼 通過touches方法監聽view觸摸事件&#xff0c;有很明顯的幾個缺點 必須得自定義view 由于是在view內部的to…

iOS手勢操作簡介(四)

當事件傳遞到相應的UIResponder后&#xff0c;會首先調用&#xff1a; hitTest:withEvent: return (UIView *) UIApplication -> UIWindow 什么時候調用&#xff1a;當事件傳遞給一個控件的時候就會調用 作用&#xff1a;找最合適的viewhitTest:withEvent: return (UIView…

ASP.NET Core Web 應用程序系列(二)- 在ASP.NET Core中使用Autofac替換自帶DI進行批量依賴注入(MVC當中應用)...

在上一章中主要和大家分享在MVC當中如何使用ASP.NET Core內置的DI進行批量依賴注入&#xff0c;本章將繼續和大家分享在ASP.NET Core中如何使用Autofac替換自帶DI進行批量依賴注入。 PS&#xff1a;本章將主要采用構造函數注入的方式&#xff0c;下一章將繼續分享如何使之能夠同…

iOS手勢操作簡介(五)

利用手勢操作實現抽屜效果&#xff1a; 第一步&#xff1a;搭建UI (void)addChildView { // left UIView *leftView [[UIView alloc] initWithFrame:self.view.bounds]; leftView.backgroundColor [UIColor greenColor]; [self.view addSubview:leftView]; _leftView…