編寫簡單多執行緒web伺服器

2021-04-20 03:44:07 字數 4041 閱讀 7765

編寫簡單多執行緒web伺服器

刺蝟@http://blog.csdn.net/littlehedgehog

下面的原理解釋參照《乙個多執行緒web伺服器例項(c,linux,詳細的web伺服器原理)》 一文:

原理:在瀏覽器中輸入乙個**,回車之後,瀏覽器會向相應主機的相應埠傳送一段報文,如果是http協議的(如平常看到的網頁的傳輸協議),就會傳送http請求報文。下面是乙個報文的例子:

我們在伺服器端把收到的資料列印出來,可以看到瀏覽器發過來的就是這個東西。當然,也可以用ethereal等抓包工具來抓獲這些報文。關於報文裡寫的是什麼意思,網上有很多資料的,google一下就有了。我們只看第一行。

get表示是要從伺服器獲取檔案,/index.html是檔案的路 徑,這個路徑是相對於伺服器端程式所在資料夾的路徑。如我的伺服器端程式放在/home/mio/program/webserver1707/裡面,那 這個index.html在伺服器上的絕對路徑就是/home/mio/program/webserver1707/index.html。如果報文裡 是get /admin/login.html http/1.1的話,那麼login.html檔案在伺服器端的路徑是/home/mio/program/webserver1707/admin /login.html.http/1.1表示的是http協議的版本是1.1.

伺服器端程式執行後,一直監聽12345端品(0-1023的埠由 iana統一分配和控制的,不要用,最好選大一些的埠號。我原來用了個1234,用不了,還是選大一點好,可以用5460之類的啊~:) ),當監聽到客戶端發來的請求後,就與客戶端建立鏈結,接收客戶端發過來的請求報文。我們如果把這些報文打出來,就可以看到就是與上面請求報文類似的東西 了。

下面我們要根據所接受的到的請求報文(get /index.html http/1.1) 來決定放給客戶端(即瀏覽器)什麼東西。這裡我們看到瀏覽器要的是index.html這樣乙個html文字,我們就在相應路徑(/home/mio /program/webserver1707/index.html)找到這個檔案,不過不要急著發給客戶端,我們要先告訴客戶端,發過去的是乙個 html檔案,讓瀏覽器做好相應的準備。怎麼讓瀏覽器知道呢?我們還是用報文,這個報文叫響應報文。報文由狀態行、首部行、實體主體三部分組成。狀態行只 有一行,它和首部行、首部行的每行之間是沒有空行的,但是首部行與實體主體之間有乙個空行,表明從這個空行開始,就是你瀏覽器要的資料了。下面是乙個用 ethereal抓到的響應報文:

[email protected]| 個性化主頁https://www.google.com/accounts/manageaccount">我的帳戶 | http://www.google.com/accounts/logout?continue=http://www.google.com/intl/zh-cn/"> 退出

..........

第乙個空行上面的就是「說明」了,下面是html**。有了說明,瀏 覽器就知道這是什麼了,拿到這段資料後,就把這些html標籤解釋成各種各樣的元素,在瀏覽器上有序地顯示出來。瀏覽器還蠻聰明的,當看到

這樣,伺服器端就找到這個.jpg影象,加上"說明"之後發給瀏覽器,瀏覽器收到後就顯示在對應的位置上。遇到包含css、js...的標籤也一樣。

如此重複,乙個完整的web就會呈現在我們眼前了。

這裡是伺服器原始碼,本來打算可以傳完整http網頁的,包括。不過傳輸一直有問題。暫時放一放了。

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#define hostlen 256

#define portnum 12345

//#define debug

int make_server_socket_q(int,int);

void error(char *err)

int make_server_socket(int port)        //num for listen

int make_server_socket_q(int port,int backlog)

/* 允許接入*/

if(listen(sock_id,3))

error("listen failed");

return sock_id;

}/* 測試是否存在 */

int check_exist(char *filename)

/* 檢測檔案型別 */

char * file_type(char *filename)

/* 報文 頭部 */

void do_head(int sock_fd,char *type)

/* 404 檔案沒找到 */

void do_nofile(char *filename,int sock_fd)

/* 處理其它命令 */

void do_unkown(int sock_fd)

/* 核心處理 從檔案中讀取 然後寫入socket */

content="text/plain";       //預設處理

sock_fp=fdopen(sock_fd,"w");

file_fp=fopen(arg,"rb");

if(file_fp!=null&&sock_fp!=null)

}/* request處理 */

int process_rq(char *request,int sock_fd)

/* 執行緒主函式 */

void thread_routine(void *fd)

int main(int argc,char *argv)

port=argc==1?portnum:atoi(argv[1]); //注意這裡如果只有乙個引數,即是設定預設埠

if((sock_id=make_server_socket(port))==-1)

return -1;

printf("now listen to the port #%d/n",port);

fflush(stdout);

while(1)

return 0;

}

python實現多執行緒web伺服器

自定義執行緒函式 def server tcpclisock,addr bufsize 1024 print waiting for the connection addr data tcpclisock.recv bufsize decode filename data.split 1 filen...

web伺服器 簡單web伺服器實現

三次握手 一般情況下是瀏覽器先傳送請求資料,c s ack 應答 三次握手成功後,才開始進行通訊資料的收發。四次揮手 一般情況下是客戶端先關閉,給瀏覽器傳送關閉資訊。如果瀏覽器傳送了關閉資訊,但是伺服器沒有回過去,較慢 那麼瀏覽器一直發是不是就會有問題?所以會等待 2msl的時間。一般為2 5分鐘。...

多執行緒伺服器

posix執行緒庫 a 與執行緒有關的函式都構成了乙個完整的系列,絕大多數函式的名字都是以 pthread 打頭的。b 要使用這些庫函式,要引入標頭檔案。c 鏈結這些執行緒庫函式時要使用編譯命令的 lpthread 選項。int pthread create pthread t thread,con...