Winsock I/O 模型:性能和可擴展性的關鍵

目錄

引言

Select模型

簡介

主要特點

優點

缺點

工作原理

示例用法

WSAAsyncSelect異步I/O模型

簡介

工作原理

主要步驟

優點

缺點

示例代碼

WSAEventSelect事件選擇模型

簡介

工作原理

主要步驟

優點

缺點

示例代碼

重疊I/O模型

簡介

工作原理

主要優勢

應用場景

示例代碼

完成端口模型

簡介

工作原理

主要步驟

線程池

應用場景

示例代碼

結論


引言


????????在網絡編程領域,輸入/輸出(I/O)模型是數據傳輸的基礎架構。在Windows系統中,Winsock(Windows Sockets API)提供了多種I/O模型以支持不同的網絡通信需求。

????????本文將詳細介紹Winsock提供的五種主要I/O模型:select模型、WSAAsyncSelect異步I/O模型、WSAEventSelect事件選擇模型、重疊I/O模型和完成端口模型。

Select模型

簡介

????????Select模型是Windows Socket中最基本的一種同步I/O模型。它通過使用Select函數,開發者可以監視一組socket的狀態變化,例如可讀性、可寫性、錯誤狀態等。Select模型使用輪詢機制,讓開發者在一個線程內管理多個socket,有效減少資源的負擔。然而,由于Select模型的低效輪詢機制,在處理大規模并發連接時會面臨性能瓶頸。

主要特點
  • **簡單易用:**Select模型的API簡單易用,易于理解和使用。
  • **多socket管理:**Select模型可以同時監視多個socket,并等待其中任何一個變為可讀、可寫或發生異常。
  • **跨平臺支持:**Select模型在大多數操作系統上都得到了廣泛的支持,包括Windows、Linux和macOS。
優點
  • **易于使用:**Select模型的簡單API和直接的方法使其成為開發人員的理想選擇。
  • **資源效率:**通過在單個線程內管理多個socket,Select模型最大限度地減少了資源消耗和開銷。
  • **跨平臺兼容性:**Select模型在不同平臺上的廣泛支持確保了其在各種環境中的適用性。
缺點
  • **輪詢效率低下:**Select模型的輪詢機制,即順序檢查每個socket的狀態,會導致性能下降,尤其是在處理大量socket時。
  • **并發限制:**Select模型的單線程特性可能會限制并發性,從而阻礙對高水平并發I/O操作要求苛刻的應用程序的性能。
  • **可擴展性問題:**隨著連接和I/O操作數量的增加,Select模型的輪詢機制可能會不堪重負,導致可擴展性問題。
工作原理

????????Select模型通過使用稱為“fd_set”的數據結構來存儲要監視的socket描述符來工作。fd_set結構包含三個集合:

  • **readfds:**包含可讀socket描述符。
  • **writefds:**包含可寫socket描述符。
  • **exceptfds:**包含遇到錯誤的socket描述符。

????????開發人員可以將感興趣的socket描述符添加到相應的fd_set中。然后,他們調用Select函數,并將fd_set作為參數傳遞。Select函數將阻塞,直到至少一個socket變為可讀、可寫或遇到錯誤。返回后,Select函數會更新fd_set結構,指示哪些socket已過渡到準備狀態。然后,開發人員可以檢查修改后的fd_set來處理相應的I/O操作。

示例用法

以下代碼片段演示了使用Select模型監視兩個socket的基本用法:

#include <winsock.h>int main() {// 初始化WinsockWSADATA wsaData;int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);if (iResult != 0) {printf("WSAStartup failed: %d\n", iResult);return 1;}// 創建socketSOCKET sock1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sock1 == INVALID_SOCKET) {printf("socket failed: %d\n", WSAGetLastError());WSACleanup();return 1;}SOCKET sock2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sock2 == INVALID_SOCKET) {printf("socket failed: %d\n", WSAGetLastError());closesocket(sock1);WSACleanup();return 1;}// 綁定socketsockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(8080);serverAddr.sin_addr.s_addr = INADDR_ANY;int iBindResult1 = bind(sock1, (SOCKADDR*)&serverAddr, sizeof(serverAddr));if (iBindResult1 == SOCKET_ERROR) {printf("bind failed: %d\n", WSAGetLastError());closesocket(sock1);closesocket(sock2);WSACleanup();return 1;}int iBindResult2 = bind(sock2, (SOCKADDR*)&serverAddr, sizeof(serverAddr));if (iBindResult2 == SOCKET_ERROR) {printf("bind failed: %

WSAAsyncSelect異步I/O模型

簡介

????????WSAAsyncSelect 異步 I/O 模型提供了一種異步的方式來通知應用程序 socket 的狀態變化。與 Select 模型的輪詢機制不同,WSAAsyncSelect 使用消息隊列來傳遞通知,使應用程序無需主動查詢 socket 的狀態即可獲知其變化。

工作原理

????????WSAAsyncSelect 模型的核心是將 socket 與一個消息隊列關聯起來。當 socket 的狀態發生變化時,例如有數據可讀或可寫,系統就會向該消息隊列發送一條消息。應用程序可以通過處理消息隊列中的消息來響應相應的 I/O 操作。

主要步驟
  1. **創建消息隊列:**應用程序首先需要創建一個消息隊列,用于接收來自系統的通知消息。
  2. **關聯 socket 和消息隊列:**使用 WSAAsyncSelect 函數將 socket 與消息隊列關聯起來。
  3. **設置事件:**應用程序可以設置 WSAAsyncSelect 函數的參數,指定要通知的事件類型,例如可讀、可寫或錯誤。
  4. **處理消息:**應用程序需要有一個消息處理循環來不斷地從消息隊列中獲取消息。
  5. **關閉 socket:**當應用程序不再需要使用 socket 時,需要使用 closesocket 函數關閉 socket 并取消其與消息隊列的關聯。
優點
  • **異步通知:**應用程序無需主動查詢 socket 的狀態,可以提高應用程序的響應速度和效率。
  • **減少資源占用:**應用程序無需使用輪詢機制來監視 socket 狀態,可以減少 CPU 資源的占用。
  • **易于實現:**WSAAsyncSelect 模型的 API 相對簡單,易于理解和實現。
缺點
  • **消息隊列延遲:**由于依賴消息隊列傳遞通知,可能會存在消息處理的延遲。
  • **可擴展性問題:**在高并發情況下,消息隊列可能會成為性能瓶頸。
示例代碼

以下代碼演示了如何使用 WSAAsyncSelect 模型來監視一個 socket:

#include <winsock.h>int main() {// 初始化 WinsockWSADATA wsaData;int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);if (iResult != 0) {printf("WSAStartup failed: %d\n", iResult);return 1;}// 創建 socketSOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sock == INVALID_SOCKET) {printf("socket failed: %d\n", WSAGetLastError());WSACleanup();return 1;}// 創建消息隊列MSGQUEUE hMsgQueue = CreateMsgQueue(NULL, 0, 0);if (hMsgQueue == NULL) {printf("CreateMsgQueue failed: %d\n", GetLastError());closesocket(sock);WSACleanup();return 1;}// 關聯 socket 和消息隊列WSAAsyncSelect(sock, hMsgQueue, WM_SOCKET_NOTIFY);// 設置事件WSAEventSelect(sock, FD_READ);// 消息處理循環MSG msg;while (GetMessage(&msg, NULL, 0, 0)) {switch (msg.message) {case WM_SOCKET_NOTIFY: {WPARAM wParam = msg.wParam;LPARAM lParam = msg.lParam;// 處理 socket 事件switch (wParam) {case FD_READ:// 處理可讀事件break;case FD_WRITE:// 處理可寫事件break;case FD_CLOSE:// 處理連接關閉事件break;case FD_ERROR:// 處理錯誤事件break;}break;}default:DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);}}// 關閉 socketclosesocket(sock);// 關閉消息隊列CloseMsgQueue(hMsgQueue);// 清理 WinsockWSACleanup();return 0;
}

WSAEventSelect事件選擇模型

簡介

????????WSAEventSelect 模型是 Winsock 提供的另一種事件驅動的異步 I/O 方式。與 WSAAsyncSelect 模型不同,WSAEventSelect 模型使用事件對象來表示 socket 的狀態變化,而不是使用消息隊列。這種模型允許開發者為每個 socket 創建一個事件對象,并將 socket 的狀態變化與這些事件關聯。隨后,開發者可以使用 WaitForMultipleObjects 等函數來等待任何一個事件的觸發。這種模型使得事件管理更加簡潔,并且可以提供出色的性能表現。

工作原理

????????WSAEventSelect 模型的核心是將 socket 與一個或多個事件對象關聯起來。當 socket 的狀態發生變化時,例如有數據可讀或可寫,系統就會將該事件的狀態設置為已觸發。應用程序可以使用 WaitForMultipleObjects 等函數來等待任何一個事件的觸發。當一個事件被觸發時,應用程序可以根據該事件的類型來執行相應的 I/O 操作。

主要步驟
  1. **創建事件對象:**應用程序首先需要為每個 socket 創建一個事件對象。
  2. **關聯 socket 和事件對象:**使用 WSAEventSelect 函數將 socket 與事件對象關聯起來。
  3. **設置事件:**應用程序可以設置 WSAEventSelect 函數的參數,指定要通知的事件類型,例如可讀、可寫或錯誤。
  4. **等待事件:**應用程序可以使用 WaitForMultipleObjects 等函數來等待任何一個事件的觸發。
  5. **處理事件:**當一個事件被觸發時,應用程序可以使用 GetEventObjectIdentity 函數來確定哪個 socket 的狀態發生了變化,然后根據該事件的類型來執行相應的 I/O 操作。
  6. **關閉 socket:**當應用程序不再需要使用 socket 時,需要使用 closesocket 函數關閉 socket 并取消其與事件對象的關聯。
優點
  • **簡潔的事件管理:**WSAEventSelect 模型使用事件對象來表示 socket 的狀態變化,使得事件管理更加簡潔。
  • **出色的性能表現:**WSAEventSelect 模型可以提供出色的性能表現,因為它避免了消息隊列的開銷。
  • **易于擴展:**WSAEventSelect 模型易于擴展,因為它允許為每個 socket 創建多個事件對象。
缺點
  • **編程復雜度略高:**與 Select 模型相比,WSAEventSelect 模型的編程復雜度略高,因為它需要創建和管理事件對象。
  • **需要額外的內存分配:**事件對象的創建需要額外的內存分配。
示例代碼

以下代碼演示了如何使用 WSAEventSelect 模型來監視一個 socket:

#include <winsock.h>int main() {// 初始化 WinsockWSADATA wsaData;int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);if (iResult != 0) {printf("WSAStartup failed: %d\n", iResult);return 1;}// 創建 socketSOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sock == INVALID_SOCKET) {printf("socket failed: %d\n", WSAGetLastError());WSACleanup();return 1;}// 創建事件對象WSAEVENT hEvent = WSAEventCreate(NULL, TRUE, TRUE, NULL);if (hEvent == NULL) {printf("WSAEventCreate failed: %d\n", GetLastError());closesocket(sock);WSACleanup();return 1;}// 關聯 socket 和事件對象WSAEventSelect(sock, hEvent, FD_READ | FD_WRITE);// 等待事件DWORD dwWaitResult = WaitForMultipleObjects(1, &hEvent, TRUE, INFINITE);if (dwWaitResult == WAIT_FAILED) {printf("WaitForMultipleObjects failed: %d\n", GetLastError());WSACloseEvent(hEvent);closesocket(sock);WSACleanup();return 1;}// 處理事件WSAEVENT hTriggeredEvent = NULL;DWORD dwEventCount = 0;BOOL bSuccess = WSAEnumEvents(sock, NULL, &hTriggeredEvent, 1, &dwEventCount);if (bSuccess && dwEventCount > 0) {DWORD dwEventFlags;bSuccess = WSAEventGetInfo(hTriggeredEvent, 0, NULL, &dwEventFlags);

重疊I/O模型

簡介

????????重疊 I/O 模型是 Windows 獨有的一種先進的異步 I/O 技術。它允許 I/O 操作在后臺執行,應用程序無需等待 I/O 操作完成即可繼續處理其他任務。與傳統的阻塞 I/O 模型相比,重疊 I/O 模型可以顯著提高應用程序的性能,尤其是在處理大量 I/O 操作的網絡應用程序中。

工作原理

????????重疊 I/O 模型的核心是使用 OVERLAPPED 結構體來管理 I/O 操作。OVERLAPPED 結構體包含以下成員:

  • hEvent:用于通知應用程序 I/O 操作完成的事件句柄。
  • Internal:保留供系統內部使用。
  • Offset:用于指示 I/O 操作要從文件或緩沖區的哪個位置開始。
  • InternalHigh:保留供系統內部使用。
  • Union:包含指向用于 I/O 操作的緩沖區的指針。

????????應用程序可以使用 WSARecvWSASend 等函數來發起重疊 I/O 操作。這些函數會將 I/O 操作的參數和 OVERLAPPED 結構體作為參數傳遞。系統會將 I/O 操作排隊并將其置于后臺執行。當 I/O 操作完成時,系統會將 hEvent 事件設置為已觸發狀態,并通知應用程序。

主要優勢
  • **提高性能:**重疊 I/O 模型可以顯著提高應用程序的性能,因為應用程序無需等待 I/O 操作完成即可繼續處理其他任務。
  • **提高響應速度:**重疊 I/O 模型可以提高應用程序的響應速度,因為應用程序可以同時處理多個 I/O 操作。
  • **降低資源占用:**重疊 I/O 模型可以降低應用程序對 CPU 資源的占用,因為 I/O 操作是在后臺執行的。
應用場景

????????重疊 I/O 模型適用于需要處理大量 I/O 操作的應用程序,例如:

  • **網絡應用程序:**Web 服務器、客戶端-服務器應用程序、P2P 應用程序等。
  • **文件 I/O 密集型應用程序:**數據庫應用程序、視頻編輯軟件、大型文件傳輸應用程序等。
示例代碼

以下代碼演示了如何使用重疊 I/O 模型從套接字中接收數據:

#include <winsock.h>int main() {// 初始化 WinsockWSADATA wsaData;int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);if (iResult != 0) {printf("WSAStartup failed: %d\n", iResult);return 1;}// 創建套接字SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sock == INVALID_SOCKET) {printf("socket failed: %d\n", WSAGetLastError());WSACleanup();return 1;}// 綁定套接字sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(8080);serverAddr.sin_addr.s_addr = INADDR_ANY;int iBindResult = bind(sock, (SOCKADDR*)&serverAddr, sizeof(serverAddr));if (iBindResult == SOCKET_ERROR) {printf("bind failed: %d\n", WSAGetLastError());closesocket(sock);WSACleanup();return 1;}// 監聽套接字int iListenResult = listen(sock, 5);if (iListenResult == SOCKET_ERROR) {printf("listen failed: %d\n", WSAGetLastError());closesocket(sock);WSACleanup();return 1;}// 接受連接sockaddr_in clientAddr;int clientAddrLen = sizeof(clientAddr);SOCKET clientSock = accept(sock, (SOCKADDR*)&clientAddr, &clientAddrLen);if (clientSock == INVALID_SOCKET) {printf("accept failed: %d\n", WSAGetLastError());closesocket(sock);WSACleanup();return 1;}// 創建事件對象WSAEVENT hEvent = WSAEventCreate(NULL, TRUE, TRUE, NULL);

完成端口模型

簡介

????????完成端口模型是 Windows Sockets 中最復雜但也是最強大的 I/O 模型。它充分利用了多核處理器的能力,提供了一個可伸縮的高性能 I/O 操作解決方案。與其他 I/O 模型相比,完成端口模型具有以下優勢:

  • **高性能:**完成端口模型可以充分利用多核處理器的能力,顯著提高 I/O 操作的性能。
  • **可伸縮性:**完成端口模型可以處理大量并發連接,并隨著硬件的升級而擴展。
  • **低延遲:**完成端口模型可以提供低延遲的 I/O 操作,非常適合對延遲敏感的應用程序。
工作原理

????????完成端口模型的核心是使用 CreateIoCompletionPort 函數創建一個或多個完成端口。完成端口是一個內核對象,用于存儲已完成 I/O 操作的通知。應用程序可以使用 AssociateSocket 函數將一個或多個套接字與完成端口關聯起來。

????????當一個套接字上的 I/O 操作完成時,系統會將一個 IO_COMPLETION_RESULT 結構體發送到與該套接字關聯的完成端口。應用程序可以使用 GetQueuedCompletionPort 函數來檢索完成端口隊列中的通知。

主要步驟
  1. **創建完成端口:**使用 CreateIoCompletionPort 函數創建一個或多個完成端口。
  2. **關聯套接字:**使用 AssociateSocket 函數將一個或多個套接字與完成端口關聯起來。
  3. **發起 I/O 操作:**使用 WSASendWSARecv 等函數發起 I/O 操作,并將 OVERLAPPED 結構體傳遞給這些函數。
  4. **檢索完成通知:**使用 GetQueuedCompletionPort 函數檢索完成端口隊列中的通知。
  5. **處理完成通知:**根據 IO_COMPLETION_RESULT 結構體中的信息處理完成的 I/O 操作。
線程池

????????完成端口模型通常與線程池技術結合使用。線程池是一種管理線程的技術,可以有效地分配處理器資源進行并行計算。在完成端口模型中,應用程序可以使用線程池來處理完成的 I/O 操作。每個線程池中的線程都可以從完成端口隊列中檢索通知并處理完成的 I/O 操作。

應用場景

完成端口模型適用于需要處理大量并發 I/O 操作的應用程序,例如:

  • **網絡應用程序:**Web 服務器、高性能網絡應用、游戲服務器等。
  • **文件 I/O 密集型應用程序:**數據庫應用程序、視頻編輯軟件、大型文件傳輸應用程序等。
示例代碼

以下代碼演示了如何使用完成端口模型從套接字中接收數據:

#include <winsock.h>int main() {// 初始化 WinsockWSADATA wsaData;int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);if (iResult != 0) {printf("WSAStartup failed: %d\n", iResult);return 1;}// 創建完成端口HANDLE hCompletionPort = CreateIoCompletionPort(NULL, NULL, 0, 0);if (hCompletionPort == NULL) {printf("CreateIoCompletionPort failed: %d\n", GetLastError());WSACleanup();return 1;}// 創建套接字SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sock == INVALID_SOCKET) {printf("socket failed: %d\n", WSAGetLastError());CloseHandle(hCompletionPort);WSACleanup();return 1;}// 綁定套接字sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(8080);serverAddr.sin_addr.s_addr = INADDR_ANY;int iBindResult = bind(sock, (SOCKADDR*)&serverAddr, sizeof(serverAddr));if (iBindResult == SOCKET_ERROR) {printf("bind failed: %d\n", WSAGetLastError());closesocket(sock);CloseHandle(hCompletionPort);WSACleanup();return 1;}// 監聽套接字int iListenResult = listen(sock, 5);if (iListenResult == SOCKET_ERROR) {

結論


????????Winsock為Windows下的網絡編程提供了多樣化的I/O模型,每種模型都適用于不同場景的需求。無論是簡單的select模型,還是高效的完成端口模型,了解它們的工作方式、優缺點對于開發高質量的網絡應用程序都至關重要。掌握這些I/O模型,將有助于你建構出更穩定、更高性能的網絡通信解決方案。

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

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

相關文章

網絡編程 一

一、UDP socket api的使用 Java 把系統原生的封裝了. 核心的類有兩個: 1 -> DatagramSocket 操作系統中,有一類文件,就叫socket文件. socket文件,抽象表示了 " 網卡"這樣的硬件設備. 進行網絡通信最核心的硬件設備網卡 通過網卡發送數據,就是寫…

各手機品牌【短信收件箱數據庫列名】對比:inbox的column橫向對比

參考資料: https://blog.csdn.net/qq_35427437/article/details/85678647 https://www.cnblogs.com/bill-technology/p/4130917.html <font colorred>threads是存放會話的數據表&#xff0c;sms是存放短信的數據表&#xff0c;pdu是存放彩信的數據表</font> | 含義…

0基礎從前端到Web3 —— Mine Clearance Frontend(二)

在一的基礎上繼續往下&#xff0c;本篇主要是鏈上調用部分&#xff0c;讓整個項目可以進行最基本的掃雷游戲。 S u i M o v e \mathit {Sui\ Move} Sui Move 鏈上部署的自主實現的簡單掃雷游戲可以點擊查看&#xff0c;只不過這里將區域大小擴大為了 10 20 \text {10}\ \tim…

力扣Hot100-73矩陣置零(標記數組)

給定一個 m x n 的矩陣&#xff0c;如果一個元素為 0 &#xff0c;則將其所在行和列的所有元素都設為 0 。請使用 原地 算法。 示例 1&#xff1a; 輸入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 輸出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]]示例 2&#xff1a; 輸入&…

大模型面試--大模型(LLMs)基礎面

大模型&#xff08;LLMs&#xff09;基礎面 1. 目前主流的開源模型體系有哪些&#xff1f; 目前主流的開源大模型體系有以下幾種&#xff1a; 1. Transformer 系列 Transformer 模型是深度學習中的一類重要模型&#xff0c;尤其在自然語言處理&#xff08;NLP&#xff09;領…

JavaWeb Sevelet學習 創建Sevelet程序

Servlet 是JavaWeb中的開發動態Web一門技術 是由Sun公司提供的一個接口&#xff0c;允許開發者編寫運行在服務器&#xff08;Tomcat&#xff09;上的Java程序&#xff0c;這些程序可以 生成動態網頁內容&#xff0c; 響應客戶端的請求。簡單來說&#xff0c;Servlet就是Java E…

今日arXiv最熱大模型論文:LoRA又有新用途,學得少忘得也少,成持續學習關鍵!

自大模型&#xff08;LLM&#xff09;誕生以來&#xff0c;苦于其高成本高消耗的訓練模式&#xff0c;學界和業界也在努力探索更為高效的參數微調方法。其中Low-Rank Adaptation&#xff08;LoRA&#xff09;自其誕生以來&#xff0c;就因其較低的資源消耗而受到廣泛關注和使用…

Spring MVC八股文面試題及參考答案(4萬字長文)

目錄 什么是Spring MVC? 解釋MVC模式及其在Spring MVC中的實現。 Spring MVC和Struts的區別是什么?

瑞芯微RV1126——交叉編譯與移植

一、搭建這個nfs服務掛載 (1) sudo apt install nfs-kernel-server (2) 然后在你的ubuntu創建一個nfs共享目錄&#xff1a; (3) sudo /etc/init.d/nfs-kernel-server restart 重啟nfs服務 (4) 修改配置文件: sudo vim /etc/exports 在這個配置文件里面添加&#xff1a;/hom…

C語言/數據結構——每日一題(設計循環隊列)

一.前言 上一次我們分享了關于隊列的基本實現——https://blog.csdn.net/yiqingaa/article/details/139033067?spm1001.2014.3001.5502 現在我們將使用隊列知識來解決問題——設計循環隊列&#xff1a;https://leetcode.cn/problems/design-circular-queue/submissions/533299…

50.WEB滲透測試-信息收集-CDN識別繞過(3)

免責聲明&#xff1a;內容僅供學習參考&#xff0c;請合法利用知識&#xff0c;禁止進行違法犯罪活動&#xff01; 內容參考于&#xff1a; 易錦網校會員專享課 上一個內容&#xff1a;49.WEB滲透測試-信息收集-CDN識別繞過&#xff08;2&#xff09; 關于cdn的識別方法內容…

Leecode熱題100--73:矩陣置零

題目&#xff1a; 給定一個 m x n 的矩陣&#xff0c;如果一個元素為 0 &#xff0c;則將其所在行和列的所有元素都設為 0 。請使用 原地 算法。 C&#xff1a; 思路&#xff1a; 可以使用兩個數組來記錄哪些行和列需要被置零。 首先&#xff0c;我們遍歷整個矩陣&#xff0c;…

設計模式--享元模式

引言 享元模式&#xff08;Flyweight Pattern&#xff09;作為一種高效節省內存的結構型設計模式&#xff0c;其核心在于通過共享技術有效支持大量細粒度對象的重用&#xff0c;從而減少內存占用&#xff0c;提高系統性能。特別是在處理大量相似對象的場景下&#xff0c;享元模…

智慧監獄人員行為識別監測系統

智慧監獄人員行為識別監測系統是基于神經網絡AI視覺智能分析算法開發的技術。智慧監獄人員行為識別監測系統利用現場監控攝像頭&#xff0c;通過對人體活動骨架的結構化分析&#xff0c;根據人體運動軌跡定義了多種異常行為&#xff0c;從而實現對監舍內的靜坐不動、離床、攀高…

Tron節點監控腳本使用說明

文章目錄 一、配置二、腳本編寫2.1 Python腳本--監控節點是否正在同步2.1.1 pyton腳本腳本示例2.1.2 使用說明2.2.3 腳本監控內容說明 2.2 Shell腳本--綜合情況監控2.2.1 shell腳本示例2.2.2 使用說明2.2.3 腳本監控內容說明 最近搭建了TRON節點&#xff0c;為了防止節點在生產…

Mixiy(米思齊)安裝

Mixiy(米思齊)安裝 官網地址&#xff1a;愛上米思齊 打開官網&#xff0c;選擇下圖的軟件進行下載 復制提取碼&#xff0c;點擊鏈接跳轉到網盤進行下載&#xff0c;選擇(RC4完整版) 下載完成后&#xff0c;解壓到合適的位置&#xff0c;進入文件夾&#xff0c;雙擊Mixly.exe即…

Docker 部署Jenkins

1、運行鏡像 docker run --namejenkins \--restartalways \--privilegedtrue \-u root \-p 8080:8080 \-p 50000:50000 \-v /home/docker/jenkins/jenkins_home:/var/jenkins_home \-v /usr/bin/docker:/usr/bin/docker \-v /var/run/docker.sock:/var/run/docker.sock \-e TZ…

【Crypto】MD5

文章目錄 MD5解題感悟 MD5 提示的很明顯MD5 小小flag&#xff0c;拿下&#xff01; 解題感悟 沒啥感悟…

Java輸入與輸出詳解

Java輸入和輸出 前言一、Java打印Hello World二、輸出到控制臺基本語法代碼示例格式化字符串 三、從鍵盤輸入讀入一個字符正確寫法 使用 Scanner 讀取字符串/整數/浮點數使用 Scanner 循環讀取 N 個數字 前言 推薦一個網站給想要了解或者學習人工智能知識的讀者&#xff0c;這…

使用 Java 和 MyBatis 實現動態排序的多表查詢

相關 java實現一個根據字段和排序方式進行排序 java實現自定義排序 自定義動態排序 前言 在Web開發中&#xff0c;前端通常會傳遞一些參數來決定數據的排序方式&#xff0c;例如排序字段和排序方向。本文將展示如何在 Java 項目中結合 MyBatis 實現動態排序&#xff0c;尤其…