Web伺服器端程式的實現

2022-04-11 15:47:53 字數 3812 閱讀 6548

web伺服器端程式主要是兩個部分,一部分是主函式,一部門是命令處理函式。命令處理函式比較好理解就是針對客戶端不同的命令進行處理,與客戶端進行通訊。主函式也有兩個主要的功能,第一是要對程式進行初始化,其中包括建立監聽套接字並且繫結到位址和埠上,第二是建立子程序處理對應的連線請求。

1、主函式

web伺服器的主函式中第一是初始化程式,第二就是建立子程序。父程序一直監聽,子程序進行連線處理,提高伺服器端的處理能力,提高效率,流程圖如下:

主函式中的**如下所示:

#include "

common.h

"int main(void

)

if( (pid = fork()) < 0)

else

if(pid == 0)

}close(cfd);

/*跳出迴圈後關閉連線套接字描述符,通訊結束

*/exit(

0); /*

子程序退出 */}

else

close(cfd);

/*父程序關閉連線套接字,繼續監聽 */}

return

0; /*

伺服器程式很少有退出的時候

*/}

在主函式中也可以看出來父程序用來監聽,子程序用來處理連線請求。一開始進行linuxc學習的時候學到了程序的相關的知識,這是乙個多程序的程式例項,原理很簡單,但是需要注意的是子程序與父程序資源共享,因此要在父程序進行監聽的時候要關閉連線套接字,在子程序中要關閉監聽套接字,防止父子程序中相互干擾。主函式中程序初始化呼叫的init函式,函式**如下:

int init(struct sockaddr_in *sin, int *lfd, int

sock_opt)

setsockopt(tfd, sol_socket, so_reuseaddr, &sock_opt, sizeof(int)); /*

設定套接字選項

*//*

繫結客戶端位址,具體位址沒有限制

*/if( (bind(tfd, (struct sockaddr *)sin, sizeof(struct sockaddr_in))) == -1

)

if( (listen(tfd, 20)) == -1

) *lfd =tfd;

return0;

}

2、命令處理模組

根據之前的客戶端程式可以知道伺服器端有4個函式,分別是處理get、put、cd、ls這四個命令。

do_put函式處理get命令,函式成功返回0,失敗返回-1。客戶端發過來的get命令的格式為:get arg1。

引數說明:

cfd : 連線套接字的描述符

file : 客戶端請求的檔案的路徑

int do_put(int cfd, char *file)

if( (fstat(fd, &statbuf)) == -1)

if(!s_isreg(statbuf.st_mode))

sprintf(buf,

"ok %d

", statbuf.st_size); /*

一切正常,傳送應答資訊,格式為:ok 傳送檔案的長度

*/if(my_write(cfd, buf, strlen(buf)) == -1) /*

傳送應答資訊

*/goto

end;

if ( (my_read(cfd, buf, max_line)) <= 0) /*

等待客戶端的應答資訊,應答碼是rdy

*/goto

end;

while(1)

else

}res = 0; /*

執行至此一切正常

*/end:

close(fd);

/*關閉檔案,注意不是關閉套接字

*/return

res;

}

do_get函式處理put命令,成功返回0,失敗返回-1。客戶端發過來的 put命令的格式為:put arg1 arg2

該命令將客戶端的檔案傳送至伺服器,arg1為檔案的大小,arg2為傳送檔案在伺服器端的檔案路徑。

引數說明:

cfd : 連線套接字的描述符

file : 傳送過來的檔案在伺服器端的儲存路徑

int do_get(int cfd, char *file)

else

}if( (fstat(fd, &statbuf)) == -1)

len =statbuf.st_size;

if(!s_isreg(statbuf.st_mode))

if(my_write(cfd, "

ok", 2) == -1) /*

傳送正確的應答碼

*/goto

end;

while(1)

else

if(len == 0

) else

/*讀取的位元組數小於0,出錯

*/goto

end;

}res = 0; /*

正常返回

*/end:

close(fd);

return

res;

}

do_cd函式處理cd命令,成功返回0,失敗返回-1,客戶端傳送過來的cd命令的格式為:put arg1

該命令進入指定的伺服器端目錄,arg1為指定目錄的路徑

引數說明:

path:指定目錄的路徑

int do_cd(char *path)

my_write(cfd,

"ok\n");

return0;

}

do_ls函式處理ls命令,成功返回0,失敗返回-1。客戶端傳送過來的ls命令的格式為:ls arg1。

該命令列出當前伺服器端目錄下的檔案,arg1為指定目錄的路徑

引數說明:

path:指定目錄的路徑

int do_ls(char *path)

if( (fstat(fd, &statbuf)) == -1)

if(!s_isreg(statbuf.st_mode))

sprintf(buf,

"ok %d

", statbuf.st_size); /*

一切正常傳送應答資訊,格式為: ok 傳送檔案的長度

*/if(my_write(cfd, buf, strlen(buf)) == -1) /*

傳送應答資訊

*/goto

end;

if ( (my_read(cfd, buf, max_line)) <= 0) /*

等待客戶端的應答資訊,應答碼是rdy

*/goto

end;

while(1)

else

}res = 0; /*

執行至此一切正常

*/end:

close(fd);

/*關閉檔案,注意不是關閉套接字

*/return

res;

}

24 實現http伺服器端

1.http hypertext transfer protocol超文字傳輸協議。超文字是可以根據客戶端請求而跳轉的結構化資訊。http協議是以超文字傳輸為目的而設計的應用層協議,是基於tcp ip實現的協議,實現該協議就相當於實現了web伺服器端。2.http協議又稱為無狀態的stateless...

WebSocket的C 伺服器端實現

由於需要在專案中增加websocket協議,與客戶端進行通訊,不想使用開源的庫,比如websocketpp,就自己根據websocket協議實現一套函式,完全使用c 實現。一 原理 websocket協議解析,已經在前面部落格裡面詳細講解過,可以參考部落格這裡就不詳細細說。伺服器端實現就是使用tcp...

多執行緒伺服器端的實現

1.單cpu系統中如何同時執行多個程序?請解釋該過程中發生的上下文切換。答 只有1個cpu cpu的運算裝置core 的系統中不是也可以同時執行多個程序嗎?只是因為系統將cpu時間分成了多個微小的塊後分配給了多個程序。為了分時使用cpu,需要 上下文切換 的過程。2.為何執行緒上下文切換更快?執行緒...