Socket網路程式設計 簡單Web伺服器 3

2022-04-19 11:36:07 字數 4282 閱讀 6112

上一小節已經實現了瀏覽器傳送請求,然後伺服器給出應答資訊,然後瀏覽器顯示出伺服器傳送過來的網頁。一切看起來都是那麼的美好。這一小節就準備實現可以根據位址列url的不同來返回指定的網頁。目前還不考慮帶引數的問題。

stat函式

#include

int stat(const char *restrict pathname,struct stat * restrict buf);

int fstat(int filedes,struct stat * buf);

int lstat(const char *restrict pathname,struct stat * restrict buf);

給出pathname,stat函式就返回與此命名檔案有關的資訊結構。fstat函式獲取已在描述符filedes上開啟檔案的有關資訊。lstat函式類似與stat,但是命名的檔案不是個符號鏈結。

實現指定url訪問指定目錄的web伺服器

1

int webserver::serverrequest(int

cli_fd)

224 method[i]='\0'

;25//取第乙個與第二個單詞之間的空格

26while(isspace(buf[j]) && (j

(buf)))

27 j++;

28//

擷取第二個單詞

29 i=0;30

while(!isspace(buf[j]) && (i

(buf)))

3135 url[i]='\0'

;3637if(strcasecmp(method,"

get") && strcasecmp(method,"

post"))

3842

43if(strcasecmp(method,"

get")==0)44

47else

if(strcasecmp(method,"

post

")==0)48

51 cout<

此次請求的位址為:

"5253 sprintf(path,"

www%s

",url);//

這個是web伺服器的主目錄,這個以後可以處理成讀取配置檔案,這裡就先寫固定的www目錄

54if(path[strlen(path)-1]=='/'

)55 strcat(path,"

index.html

");//

同上56

57//

根據檔名,獲取該檔案的檔案資訊。如果為-1,表示獲取該檔案失敗

58if(stat(path,&st)==-1)59

64else

6570

if((st.st_mode & s_ixusr) || (st.st_mode & s_ixgrp) || (st.st_mode & s_ixoth))//

判斷該url位址所對應的檔案是否是可執行,並且是否有許可權

7174

if(cgi==0)//

如果cgi為0,那麼就表示該url所對應的檔案不是cgi程式,而是乙個簡單的靜態頁面

7578}79

80if(fork()==0)81

86close(cli_fd);

87return0;

88 }

返回頁的**

**寫好了,我在當前目錄下建立乙個www的目錄在裡面有個index.html和text.html的頁面。然後我們通過瀏覽器進行返回。得到的結果如下:

可以看出都顯示了指定的網頁資訊,而最後乙個是404頁面,可是為什麼會有亂碼呢,應該是在應答資訊**沒有指點編碼格式。所以我們在page_404這個函式裡的content-type這一行進行如下修改

1 sprintf(buf, "

content-type: text/html;charset=utf-8\r\n

");

當然還可以在html網頁上進行指定。

本小結篇幅比較少,接下來就實現傳輸乙個ico圖示吧。我們都知道乙個html網頁是通過乙個url進行查詢檔案然後以http協議傳送個瀏覽器。但是我們伺服器怎麼傳送css或js或給瀏覽器呢?怎麼知道那些是要的那些是不要的。一看是還以為很難,上網查了一下,原來很簡單的。瀏覽器接收到根據url傳送過來的html檔案,然後瀏覽器會分析這個html檔案中**的檔案,css檔案等,然後在跟伺服器建立乙個http請求,請求乙個新的檔案。在傳送的過程中,不是直接傳送過去的,而是先編織成http的格式傳送給瀏覽器,其中還要指定這個的格式,大概就是這樣了。說起來比較抽象,我用wireshark抓乙個包看看。

可以看出這個應答資訊的格式跟以前講的是一樣的。也是乙個應答頭,然後在應答頭里有個content-length屬性,裡面包含接下來要接收的檔案大小。

一開始使用下面**進行檔案的讀取

1

int webserver::page_cat(int cli_fd,file *fp)211

return0;

12 }

然後在瀏覽器進行訪問,然後就是一直訪問不到資源,一直弄到凌晨幾點。今天,想了個辦法,對於乙個位元組乙個位元組的列印出來,弄了好久才知道,原來是因為資源裡面有ascii碼為0的字元,所以導致在傳送的時候使用strlen時傳送資料會不完整。哎......這個以後要注意啊。所以我準備使用fgetc來獲取資料,要注意fgetc的返回值是int型,用char會出錯,應該沒有人跟我一樣不小心吧。

1

int webserver::page_headers(int cli_fd,char * type,int

filesize)216

int webserver::page_cat(int cli_fd,file *fp)

1724

return0;

25 }

servercathttppage函式的**如下

請求資源的型別:

"3233 resource=fopen(path,"

r");//

根據get後面的檔案嗎,將檔案開啟

34if(resource==null)//

開啟檔案失敗

好了,感覺還不錯的樣子。

參考資料: 

Socket網路程式設計 簡單Web伺服器 3

上一小節已經實現了瀏覽器傳送請求,然後伺服器給出應答資訊,然後瀏覽器顯示出伺服器傳送過來的網頁。一切看起來都是那麼的美好。這一小節就準備實現可以根據位址列url的不同來返回指定的網頁。目前還不考慮帶引數的問題。stat函式 include int stat const char restrict p...

利用socket程式設計實現簡單的web伺服器

本博文主要利用socket 程式設計,實現簡單的web伺服器,客戶端能正常訪問這個伺服器 接收資訊,返回響應 file path self.parse request new client socket,ip port if file path file path index.html respon...

網路程式設計 Socket程式設計

一 網路部分 1.ip 2.埠號 在網路協議中使用埠號識別主機上不同的程序,不同的埠對應於不同的服務 應用程式 3.協議 tcp二 socket部門socket通訊基本流程圖 根據socket通訊基本流程圖,總結通訊的基本步驟 伺服器端 第一步 建立乙個用於監聽連線的socket對像 第二步 用指定...