上一小節已經實現了瀏覽器傳送請求,然後伺服器給出應答資訊,然後瀏覽器顯示出伺服器傳送過來的網頁。一切看起來都是那麼的美好。這一小節就準備實現可以根據位址列url的不同來返回指定的網頁。目前還不考慮帶引數的問題。
stat函式
#include實現指定url訪問指定目錄的web伺服器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,但是命名的檔案不是個符號鏈結。
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, "當然還可以在html網頁上進行指定。content-type: text/html;charset=utf-8\r\n
");
本小結篇幅比較少,接下來就實現傳輸乙個ico圖示吧。我們都知道乙個html網頁是通過乙個url進行查詢檔案然後以http協議傳送個瀏覽器。但是我們伺服器怎麼傳送css或js或給瀏覽器呢?怎麼知道那些是要的那些是不要的。一看是還以為很難,上網查了一下,原來很簡單的。瀏覽器接收到根據url傳送過來的html檔案,然後瀏覽器會分析這個html檔案中**的檔案,css檔案等,然後在跟伺服器建立乙個http請求,請求乙個新的檔案。在傳送的過程中,不是直接傳送過去的,而是先編織成http的格式傳送給瀏覽器,其中還要指定這個的格式,大概就是這樣了。說起來比較抽象,我用wireshark抓乙個包看看。
可以看出這個應答資訊的格式跟以前講的是一樣的。也是乙個應答頭,然後在應答頭里有個content-length屬性,裡面包含接下來要接收的檔案大小。
一開始使用下面**進行檔案的讀取
1然後在瀏覽器進行訪問,然後就是一直訪問不到資源,一直弄到凌晨幾點。今天,想了個辦法,對於乙個位元組乙個位元組的列印出來,弄了好久才知道,原來是因為資源裡面有ascii碼為0的字元,所以導致在傳送的時候使用strlen時傳送資料會不完整。哎......這個以後要注意啊。所以我準備使用fgetc來獲取資料,要注意fgetc的返回值是int型,用char會出錯,應該沒有人跟我一樣不小心吧。int webserver::page_cat(int cli_fd,file *fp)211
return0;
12 }
1servercathttppage函式的**如下int webserver::page_headers(int cli_fd,char * type,int
filesize)216
int webserver::page_cat(int cli_fd,file *fp)
1724
return0;
25 }
請求資源的型別:
"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對像 第二步 用指定...