HTTP( ,超文本傳輸協議)是一種用于分布式、協作式和超媒體信息系統的應用層協議。HTTP 是萬維網的數據通信的基礎。
請求方法
方法意義
請求一些選項信息,允許客戶端查看服務器的性能
GET
請求指定的頁面信息,并返回實體主體
HEAD
類似于 get 請求寫文件符號的使用順序,只不過返回的響應中沒有具體的內容,用于獲取報頭
POST
向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改
PUT
從客戶端向服務器傳送的數據取代指定的文檔的內容
請求服務器刪除指定的頁面
TRACE
回顯服務器收到的請求,主要用于測試或診斷
狀態碼(-Code)
2xx:表示成功,如接收或知道了3xx:表示重定向,如要完成請求還必須采取進一步的行動4xx:表示客戶的差錯,如請求中有錯誤的語法或不能完成5xx:表示服務器的差錯,如服務器失效無法完成請求更多狀態碼:菜鳥教程 . HTTP狀態碼其他協議SNMP( ,簡單網絡管理協議)構成了互聯網工程工作小組(IETF, Task Force)定義的 協議族的一部分。該協議能夠支持網絡管理系統,用以監測連接到網絡上的設備是否有任何引起管理上關注的情況。網絡編程 中的 read()、write() 函數
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
read()write() 中 TCP 的三次握手建立連接
我們知道 TCP 建立連接要進行 “三次握手”,即交換三個分組。大致流程如下:
客戶端向服務器發送一個 SYN J服務器向客戶端響應一個 SYN K,并對 SYN J 進行確認 ACK J+1客戶端再想服務器發一個確認 ACK K+1
只有就完了三次握手,但是這個三次握手發生在 的那幾個函數中呢?請看下圖:
中發送的 TCP 三次握手
從圖中可以看出:
當客戶端調用 時,觸發了連接請求,向服務器發送了 SYN J 包,這時 進入阻塞狀態; 服務器監聽到連接請求,即收到 SYN J 包,調用 函數接收請求向客戶端發送 SYN K ,ACK J+1,這時 進入阻塞狀態; 客戶端收到服務器的 SYN K ,ACK J+1 之后,這時 返回,并對 SYN K 進行確認; 服務器收到 ACK K+1 時, 返回,至此三次握手完畢,連接建立。 中 TCP 的四次握手釋放連接
上面介紹了 中 TCP 的三次握手建立過程,及其涉及的 函數。現在我們介紹 中的四次握手釋放連接的過程,請看下圖:
中發送的 TCP 四次握手
圖示過程如下:
某個應用進程首先調用 close 主動關閉連接,這時 TCP 發送一個 FIN M;另一端接收到 FIN M 之后,執行被動關閉,對這個 FIN 進行確認。它的接收也作為文件結束符傳遞給應用進程,因為 FIN 的接收意味著應用進程在相應的連接上再也接收不到額外數據;一段時間之后,接收到文件結束符的應用進程調用 close 關閉它的 。這導致它的 TCP 也發送一個 FIN N;接收到這個 FIN 的源發送端 TCP 對它進行確認。
這樣每個方向上都有一個 FIN 和 ACK。
數據庫范式設計模式各大設計模式例子參考:CSDN專欄 . C++ 設計模式 系列博文
設計模式工程目錄
單例模式
單例模式例子
抽象工廠模式
抽象工廠模式例子
適配器模式
適配器模式例子
橋接模式
橋接模式例子
觀察者模式
觀察者模式例子
設計模式的六大原則鏈接裝載庫內存、棧、堆
一般應用程序內存空間有如下區域:
棧
棧保存了一個函數調用所需要的維護信息,常被稱為堆棧幀(Stack Frame)或活動記錄( ),一般包含以下幾方面:
堆
堆分配算法:
“段錯誤( fault)” 或 “非法操作,該內存地址不能 read/write”
典型的非法指針解引用造成的錯誤。當指針指向一個不允許讀寫的內存地址,而程序卻試圖利用指針來讀或寫該地址時,會出現這個錯誤。
普遍原因:
編譯鏈接各平臺文件格式平臺可執行文件目標文件動態庫/共享對象靜態庫
exe
obj
dll
lib
Unix/Linux
ELF、out
o
so
a
Mac
Mach-O
o
dylib、tbd、
a、
編譯鏈接過程預編譯(預編譯器處理如 #、# 等預編譯指令,生成 .i 或 .ii 文件)編譯(編譯器進行詞法分析、語法分析、語義分析、中間代碼生成、目標代碼生成、優化,生成 .s 文件)匯編(匯編器把匯編碼翻譯成機器碼,生成 .o 文件)鏈接(連接器進行地址和空間分配、符號決議、重定位,生成 .out 文件)現在版本 GCC 把預編譯和編譯合成一步,預編譯編譯程序 cc1、匯編器 as、連接器 ld
MSVC 編譯環境,編譯器 cl、連接器 link、可執行文件查看器 目標文件
編譯器編譯源代碼后生成的文件叫做目標文件。目標文件從結構上講,它是已經編譯后的可執行文件格式寫文件符號的使用順序,只是還沒有經過鏈接的過程,其中可能有些符號或有些地址還沒有被調整。
可執行文件( 的 .exe 和 Linux 的 ELF)、動態鏈接庫( 的 .dll 和 Linux 的 .so)、靜態鏈接庫( 的 .lib 和 Linux 的 .a)都是按照可執行文件格式存儲( 按照 PE-COFF,Linux 按照 ELF)目標文件格式PE 和 ELF 都是 COFF( File )的變種目標文件存儲結構段功能
File
文件頭,描述整個文件的文件屬性(包括文件是否可執行、是靜態鏈接或動態連接及入口地址、目標硬件、目標操作系統等)
.text
代碼段,執行語句編譯成的機器代碼
.data
數據段,已初始化的全局變量和局部靜態變量
.bss
BSS 段(Block by ),未初始化的全局變量和局部靜態變量(因為默認值為 0,所以只是在此預留位置,不占空間)
.
只讀數據段,存放只讀數據,一般是程序里面的只讀變量(如 const 修飾的變量)和字符串常量
.
注釋信息段,存放編譯器版本信息
.note.GNU-stack
堆棧提示段
其他段略鏈接的接口————符號
在鏈接中,目標文件之間相互拼合實際上是目標文件之間對地址的引用,即對函數和變量的地址的引用。我們將函數和變量統稱為符號(),函數名或變量名就是符號名( Name)。
如下符號表( Table):
(符號名) Value (地址)
main
0x100
Add
0x123
...
...
Linux 的共享庫( )
Linux 下的共享庫就是普通的 ELF 共享對象。
共享庫版本更新應該保證二進制接口 ABI( )的兼容
命名
.so.x.y.z
路徑
大部分包括 Linux 在內的開源系統遵循 FHS(File )的標準,這標準規定了系統文件如何存放,包括各個目錄結構、組織和作用。
動態鏈接器會在 /lib、/usr/lib 和由 /etc/ld.so.conf 配置文件指定的,目錄中查找共享庫環境變量so 共享庫的編寫使用 CLion 編寫共享庫
創建一個名為 的共享庫
.txt
cmake_minimum_required(VERSION 3.10)
project(MySharedLib)
set(CMAKE_CXX_STANDARD 11)
add_library(MySharedLib SHARED library.cpp library.h)
.h
#ifndef MYSHAREDLIB_LIBRARY_H
#define MYSHAREDLIB_LIBRARY_H
// 打印 Hello World!
void hello();
// 使用可變模版參數求和

template
T sum(T t)
{
return t;
}
template
T sum(T first, Types ... rest)
{
return first + sum(rest...);
}
#endif
.cpp
#include
#include "library.h"
void hello() {
std::cout << "Hello, World!" << std::endl;
}
so 共享庫的使用(被可執行項目調用)使用 CLion 調用共享庫
創建一個名為 的可執行項目
.txt
cmake_minimum_required(VERSION 3.10)
project(TestSharedLib)
# C++11 編譯
set(CMAKE_CXX_STANDARD 11)
# 頭文件路徑
set(INC_DIR /home/xx/code/clion/MySharedLib)
# 庫文件路徑
set(LIB_DIR /home/xx/code/clion/MySharedLib/cmake-build-debug)
include_directories(${INC_DIR})
link_directories(${LIB_DIR})
link_libraries(MySharedLib)
add_executable(TestSharedLib main.cpp)
# 鏈接 MySharedLib 庫
target_link_libraries(TestSharedLib MySharedLib)
main.cpp
#include
#include "library.h"
using std::cout;
using std::endl;
int main() {
hello();
cout << "1 + 2 = " << sum(1,2) << endl;
cout << "1 + 2 + 3 = " << sum(1,2,3) << endl;
return 0;
}
執行結果
Hello, World!
1 + 2 = 3
1 + 2 + 3 = 6

應用程序入口函數 與 函數聲明
Int WINAPI _tWinMain(
HINSTANCE hInstanceExe,
HINSTANCE,
PTSTR pszCmdLine,
int nCmdShow);
int _tmain(
int argc,
TCHAR *argv[],
TCHAR *envp[]);
應用程序類型入口點函數嵌入可執行文件的啟動函數
處理ANSI字符(串)的GUI應用程序
()
處理字符(串)的GUI應用程序
()
處理ANSI字符(串)的CUI應用程序
(Main)
處理字符(串)的CUI應用程序
(wMain)
動態鏈接庫(-Link )
的動態鏈接庫(-Link )知識點來自《核心編程(第五版)》用處注意加載 程序的搜索順序包含可執行文件的目錄 的系統目錄,可以通過 得到16 位的系統目錄,即 目錄中的 子目錄 目錄,可以通過 得到進程的當前目錄PATH 環境變量中所列出的目錄DLL 入口函數 函數
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
// 第一次將一個DLL映射到進程地址空間時調用
// The DLL is being mapped into the process' address space.
break;
case DLL_THREAD_ATTACH:
// 當進程創建一個線程的時候,用于告訴DLL執行與線程相關的初始化(非主線程執行)
// A thread is bing created.
break;
case DLL_THREAD_DETACH:
// 系統調用 ExitThread 線程退出前,即將終止的線程通過告訴DLL執行與線程相關的清理
// A thread is exiting cleanly.
break;
case DLL_PROCESS_DETACH:
// 將一個DLL從進程的地址空間時調用
// The DLL is being unmapped from the process' address space.
break;
}
return (TRUE); // Used only for DLL_PROCESS_ATTACH
}
載入卸載庫read 函數聲明
// 載入庫
HMODULE WINAPI LoadLibrary(
_In_ LPCTSTR lpFileName
);
HMODULE LoadLibraryExA(
LPCSTR lpLibFileName,
HANDLE hFile,
DWORD dwFlags

);
// 若要在通用 Windows 平臺(UWP)應用中加載 Win32 DLL,需要調用 LoadPackagedLibrary,而不是 LoadLibrary 或 LoadLibraryEx
HMODULE LoadPackagedLibrary(
LPCWSTR lpwLibFileName,
DWORD Reserved
);
// 卸載庫
BOOL WINAPI FreeLibrary(
_In_ HMODULE hModule
);
// 卸載庫和退出線程
VOID WINAPI FreeLibraryAndExitThread(
_In_ HMODULE hModule,
_In_ DWORD dwExitCode
);
顯示地鏈接到導出符號 函數聲明
FARPROC GetProcAddress(
HMODULE hInstDll,
PCSTR pszSymbolName // 只能接受 ANSI 字符串,不能是 Unicode
);
.exe 查看 DLL 信息
在 VS 的開發人員命令提示符 使用 .exe 可查看 DLL 庫的導出段(導出的變量、函數、類名的符號)、相對虛擬地址(RVA, )。如:
DUMPBIN -exports D:\mydll.dll
DLL 頭文件
// MyLib.h
#ifdef MYLIBAPI
// MYLIBAPI 應該在全部 DLL 源文件的 include "Mylib.h" 之前被定義
// 全部函數/變量正在被導出
#else
// 這個頭文件被一個exe源代碼模塊包含,意味著全部函數/變量被導入
#define MYLIBAPI extern "C" __declspec(dllimport)
#endif
// 這里定義任何的數據結構和符號
// 定義導出的變量(避免導出變量)
MYLIBAPI int g_nResult;
// 定義導出函數原型
MYLIBAPI int Add(int nLeft, int nRight);
DLL 源文件
// MyLibFile1.cpp
// 包含標準Windows和C運行時頭文件
#include
// DLL源碼文件導出的函數和變量
#define MYLIBAPI extern "C" __declspec(dllexport)
// 包含導出的數據結構、符號、函數、變量
#include "MyLib.h"
// 將此DLL源代碼文件的代碼放在此處

int g_nResult;
int Add(int nLeft, int nRight)
{
g_nResult = nLeft + nRight;
return g_nResult;
}
DLL 庫的使用(運行時動態鏈接 DLL)DLL 庫的使用(運行時動態鏈接 DLL)
// A simple program that uses LoadLibrary and
// GetProcAddress to access myPuts from Myputs.dll.
#include
#include
typedef int (__cdecl *MYPROC)(LPWSTR);
int main( void )
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(TEXT("MyPuts.dll"));
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "myPuts");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd) (L"Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
printf("Message printed from executable\n");
return 0;
}
運行庫( )典型程序運行步驟操作系統創建進程,把控制權交給程序的入口(往往是運行庫中的某個入口函數)入口函數對運行庫和程序運行環境進行初始化(包括堆、I/O、線程、全局變量構造等等)。入口函數初始化后,調用 main 函數,正式開始執行程序主體部分。main 函數執行完畢后,返回到入口函數進行清理工作(包括全局變量析構、堆銷毀、關閉I/O等),然后進行系統調用結束進程。一個程序的 I/O 指代程序與外界的交互,包括文件、管程、網絡、命令行、信號等。更廣義地講,I/O 指代操作系統理解為 “文件” 的事物。glibc 入口
-> -> exit -> _exit
其中 main(argc, argv, ) 函數在 里執行。
MSVC CRT 入口
int (void)
執行如下操作:
初始化和 OS 版本有關的全局變量。初始化堆。初始化 I/O。獲取命令行參數和環境變量。初始化 C 庫的一些數據。調用 main 并記錄返回值。檢查錯誤并將 main 的返回值返回。C 語言運行庫(CRT)
大致包含如下功能:
C語言標準庫(ANSI C)
包含:
海量數據處理音視頻其他書籍語言算法系統網絡其他復習刷題網站招聘時間崗位面試題目經驗牛客網知乎ult