網路程式設計(自制伺服器)
現在的網路應用隨處可見,無法想象生活離開了網路會變得怎樣,最常見的就是通過瀏覽器上網,在位址列輸入 URL 敲擊回車,然後瀏覽器就呈現出相應的頁面。雖然現在的網路應用五花八門,但是它們都是基於相同的程式設計模型,依賴相同的程式設計介面。
每個網路應用都是基於客戶端-服務端程式設計模型的,採用這個模型,一個應用是由一個伺服器程式和一個或多個客戶端程式組成。由伺服器管理著某種資源,通過操作這些資源來為客戶端提供某種服務。需要注意的是,客戶端和服務端是程式,而不是我們常提到的機器或主機。
在系統級 I/O中已經提到過,網路也僅僅是一種檔案而已。一個插到 I/O 匯流排擴充套件槽的網路介面卡提供了網路的物理介面。從網路上接收到的資料從介面卡經過 I/O 和記憶體匯流排複製到記憶體;當然資料也同樣可以從記憶體複製到網路。
網際網路絡由大大小小的區域網和廣域網組成,這些區域網和廣域網可能採用了完全不同和不相容的技術,網際網路絡需要解決的問題是把這些不相容的網路連線起來。解決辦法就是一層執行在每臺機器和路由器上的協議軟體,這種解決方案隨處可見,比如 java 之所以誇平臺是因為不同平臺上的 JVM 做了適配。
這個協議軟體控制路由器和主機如何協同工作來實現資料傳輸,在命名上定義一種統一的主機地址格式消除差異;在資料傳輸上通過定義一種把資料位捆綁成不連續的片(包)來消除差異,一個包由包頭和有效載荷組成,包頭包括包的大小以及源主機和目的主機的地址,有效載荷包括從源主機發出的資料位。
全球 IP 因特網是最著名最成功的網際網路絡實現,每臺因特網主機都執行實現了 TCP/IP 協議的軟體。一個 IP 地址就是一個 32 位無符號整數,如下是 IP 網路程式存放的 IP 地址結構,它總是以大端法(網路位元組順序)存放。
struct in_addr {
uint32_t s_addr;
}
因特網客戶端和伺服器相互通訊使用的是 IP 地址,但是這對於人們而言太不友好了,所以因特網定義了一組更加人性化的域名,並且定義了域名集合和 IP 地址集合之間的對映。在 1988 年之前,這個對映都是通過一個叫做HOSTS.TXT
的文字檔案來手工維護的,此後改為通過 DNS(域名系統)來維護。
客戶端和服務端通過在連線
上傳送和接收位元組流來通訊,這個連線是點對點的,並且是全雙工的。一個套接字
就是連線的一個端點,每個套接字都有相應的套接字地址,由一個因特網地址和一個 16 位整數埠組成。客戶端套接字地址中的埠是核心自動隨機分配的,稱之為臨時埠;而服務端通常是很著名的埠,比如 Web 伺服器用 80 埠,電子郵件伺服器用 25 埠,並且每個知名埠都有其相應的服務名。下面是套接字地址的結構。
// _in 是 internet 的縮寫
struct scoket_in {
uint16_t sin_family; // 協議族
uint16_t sin_port; // 埠號
struct sin_addr; // IP 地址
unsigned char sin_zero[8]; // sizeof(struct sockaddr)
}
struct socketaddr {
uint16_t sa_family;
char sa_data[14];
}
核心提供了編寫網路應用所需要的函式,基本看函式名稱就知道它的功能了,下面展示了一小部分函式。
int socket(int domain, int type, int protocol);
int connect(int clientfd, const struct sockadd *addr,
socklen_t addrlen);
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
int listen(int sockfd, int backlog);
int accept(int listenfd, struct sockaddr *addr,
int *addrlen);
int getaddrinfo(const char *host, const char *service,
const struct addrinfo *hints,
struct addrinfo **result);
int getnameinfo(const struct sockaddr *sa,
socklen_t salen, char *host, size_t hostlen,
char *service, size_t servlen, int flags);
............
像用於轉換二進位制和字串表示的getaddrinfo()
、getnameinfo()
函式是可重入的。通過核心提供的這些函式就可以編寫出自己的 web 伺服器。
可重入函式主要用於多工系統中,簡單講就是可中斷函式,在這個函式執行的任何階段打斷它,作業系統去呼叫另一段程式碼,再返回控制時不會出現什麼錯誤。因為它除了使用自己棧上的變數外不依賴於任何環境。注意可重入函式不一定是執行緒安全的。
最後是原書作者自己實現的一個 TINY Wed 伺服器,用 C 實現的,在 linux 環境下編譯執行即可訪問,下圖是這個伺服器執行的效果,訪問連結http://127.0.0.1:8000/cgi-bin/adder?3&7
就可以得到運算結果。整個程式程式碼也不長,我準備好好看看再抄一遍,原始碼可訪問連結。
相關文章
- C語言+圖形程式設計——自制象棋C語言程式設計
- 程式設計師如何自制酒店 Wi-Fi?程式設計師
- 網路通訊程式設計程式設計
- 網路協程程式設計程式設計
- Socket 程式設計 (網路篇)程式設計
- python網路程式設計學習筆記(3):socket網路伺服器Python程式設計筆記伺服器
- Python網路Socket程式設計Python程式設計
- python 網路篇(網路程式設計)Python程式設計
- 《自制程式語言》封面設計方案徵集意見
- 在手機上程式設計:自制的小飛可程式設計複數計算器(小飛計算器)程式設計
- kestrel網路程式設計--開發redis伺服器程式設計Redis伺服器
- linux c網路網路程式設計面試題收集Linux程式設計面試題
- HUST-計算機網路實驗-socket程式設計計算機網路程式設計
- python網路-Socket之TCP程式設計(26)PythonTCP程式設計
- Java的網路功能與程式設計 一 (轉)Java程式設計
- Java中神經網路Triton GPU程式設計Java神經網路GPU程式設計
- 程式設計路漫漫程式設計
- 伺服器網路程式設計之執行緒模型伺服器程式設計執行緒模型
- 5種伺服器網路程式設計模型講解伺服器程式設計模型
- 網路遊戲直播原始碼自制開源版APP遊戲原始碼APP
- Linux 高效能伺服器程式設計- Linux 網路程式設計基礎 APILinux伺服器程式設計API
- Web伺服器程式設計Web伺服器程式設計
- NTP伺服器(網路時鐘伺服器)助力河北交投高速網路建設伺服器
- 【go網路程式設計】-HTTP程式設計Go程式設計HTTP
- C++ 高效能伺服器網路框架設計細節C++伺服器框架
- Java 網路程式設計(TCP程式設計 和 UDP程式設計)Java程式設計TCPUDP
- 程式設計師面試常問計算機網路問題程式設計師面試計算機網路
- C語言Socket程式設計(計算機網路作業)C語言程式設計計算機網路
- 我來談談網路設計,程式設計,網管設計三者群體的差異 (轉)程式設計
- 網路安全程式設計 windowns防火牆培訓程式設計防火牆
- 關於程式設計師寫文件(網路轉載)程式設計師
- 系統程式設計-網路-tcp客戶端伺服器程式設計模型(續)、連線斷開、獲取連線狀態場景程式設計TCP客戶端伺服器模型
- acl 伺服器程式設計框架設計要點伺服器程式設計框架
- JAVA網路程式設計(2)TCP程式設計Java程式設計TCP
- 程式設計和網路程式設計入門程式設計
- Linux 伺服器程式設計Linux伺服器程式設計
- golang http 伺服器程式設計GolangHTTP伺服器程式設計
- 網路程式設計程式設計