Tinyhttpd實戰三:源碼解析

代碼中幾個令人疑惑的地方

"將sin_addr設置爲INADDR_ANY"的含義是什麼?

問:
  很多書上都說“將sin_addr設置爲INADDR_ANY,則表示所有的IP地址,也即所有的計算機”,這樣的解說讓人費解。

答:

INADDR_ANY轉換過來就是0.0.0.0,泛指本機的意思,也就是表示本機的所有IP,因爲有些機子不止一塊網卡,多網卡的情況下,這個就表示所有網卡ip地址的意思。

當服務器的監聽地址是INADDR_ANY時,意思不是監聽所有的客戶端IP。而是服務器端的IP地址可以隨意配置,這樣使得該服務器端程序可以運行在任意計算機上,可使任意計算機作爲服務器,便於程序移植。將INADDR_ANY換成127.0.0.1也可以達到同樣的目的。這樣,當作爲服務器的計算機的IP有變動或者網卡數量有增減,服務器端程序都能夠正常監聽來自客戶端的請求。我是這麼理解的。

比如一臺電腦有3塊網卡,分別連接三個網絡,那麼這臺電腦就有3個ip地址了,如果某個應用程序需要監聽某個端口,那他要監聽哪個網卡地址的端口呢?如果綁定某個具體的ip地址,你只能監聽你所設置的ip地址所在的網卡的端口,其它兩塊網卡無法監聽端口,如果我需要三個網卡都監聽,那就需要綁定3個ip,也就等於需要管理3個套接字進行數據交換,這樣豈不是很繁瑣?所以出現INADDR_ANY,你只需綁定INADDR_ANY,管理一個套接字就行,不管數據是從哪個網卡過來的,只要是綁定的端口號過來的數據,都可以接收到。
參考博客

pthread_create()

原型:int pthread_create((pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)

用法:#include <pthread.h>

功能:創建線程(實際上就是確定調用該線程函數的入口點),在線程創建以後,就開始運行相關的線程函數

說明:
thread:線程標識符;

attr:線程屬性設置;

start_routine:線程函數的起始地址;

arg:傳遞給start_routine的參數

返回值:成功,返回0;出錯,返回-1。

pthread_create(&newthread , NULL, (void *)accept_request, (void *)(intptr_t)client_sock)

故這行代碼即爲創建一個新的線程完成當前客戶端的請求(傳入客戶端套接字),創建新線程是爲了同時爲多臺客戶端進行服務

pipe管道 父子進程通信

dup函數:

dup2(cgi_output[1], STDOUT);
dup2(cgi_input[0], STDIN);

/* filedes[0]爲管道里的讀取端
 * filedes[1]則爲管道的寫入端。*/

具體機制有點複雜,建議看該篇博客
參考博客
個人見解:由於CGI程序中調用的 scanf 和 printf默認爲STDIN 和 STDOUT,爲了與父進程通信,故使用dup2函數修改
兩者重分別定向到了兩個管道的讀取端和寫入端。則此時printf則是向父進程發送消息,scanf是接受父進程的消息(不怎麼了解CGI程序,所以不一定正確)

execute_cgi函數中創建了兩個管道:
int cgi_output[2];
int cgi_input[2];

子進程:
關閉cgi_output的讀取端和cgi_input的寫入端
使用dup2函數重定向標準輸入輸出
使CGI程序可以通過管道與父進程交互
父進程:
關閉cgi_output的寫入端和cgi_input的讀取端

在這裏插入圖片描述

發佈了48 篇原創文章 · 獲贊 8 · 訪問量 1895
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章