北京電子科技學院(BESTI)linux
實 驗 報 告編程
課程:信息安全系統設計 班級:1352 瀏覽器
姓名:銀雪純 馬悅 益西拉姆 學號:20125221 20135235 20135239安全
成績: 指導教師:婁嘉鵬 實驗日期:2015.12.8服務器
實驗密級: 預習程度: 實驗時間:15:30—17:00網絡
儀器組次: 必修/選修:必修 實驗序號:05多線程
實驗名稱: 簡單嵌入式 WEB 服務器實驗 socket
實驗目的與要求:(1)掌握在 ARM 開發板實現一個簡單 WEB 服務器的過程。 編輯器
(2)學習在 ARM 開發板上的 SOCKET 網絡編程。函數
(3)學習 Linux 下的 signal()函數的使用。
實驗儀器:
名稱 |
型號 |
數量 |
嵌入式開發平臺 |
UP-NETARM2410-CL |
1 |
PC機 |
|
1 |
實驗內容:
學習使用 socket 進行通信編程的過程,瞭解一個實際的網絡通信應用程序總體設計, 閱讀 HTTP 協議的相關內容,學習幾個重要的網絡函數的使用方法。
讀懂 HTTPD.C 源代碼。在此基礎上增長一些其餘功能。在 PC 計算機上使用瀏覽器測試 嵌入式 WEB 服務器的功能。
實驗步驟:
一、閱讀理解源碼
進入/home/bc/07_httpd 目錄,
使用 vi 編輯器或其餘編輯器閱讀理解源代碼
copy.c函數
#include <stdio.h>
static char copybuf[16384];
extern int TIMEOUT;
int copy(FILE *read_f, FILE *write_f)
{
int n;
int wrote;
alarm(TIMEOUT);
while (n = fread(copybuf,1,sizeof(copybuf),read_f)) {
alarm(TIMEOUT);
wrote = fwrite(copybuf,n,1,write_f);
alarm(TIMEOUT);
if (wrote < 1)
return -1;
}
alarm(0);
return 0;
}
alarm函數又被稱爲鬧鐘函數,alarm()用來設置信號AIGALRM通過seconds(參數)指定的秒數以後傳送給目前的進程。須要注意的有兩個地方:一個進程只能由一個鬧鐘時間,若是在調用alarm以前已經設置過鬧鐘時間,那麼任何之前的鬧鐘都會被新鬧鐘取代;若是參數seconds設置爲0,那麼以前的鬧鐘會被取消。alarm只設定一個鬧鐘,時間到達並執行其註冊函數以後,鬧鐘便失效。若是想循環設置鬧鐘,需在其註冊函數中在調用alarm函數
httpd函數
主函數:
int main(int argc, char *argv[])
{
int fd, s;
int len;
volatile int true = 1;
struct sockaddr_in ec;
struct sockaddr_in server_sockaddr;
pthread_t th_key;
void * retval;
/*第一步,進行(中斷)信號的處理*/
signal(SIGCHLD, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
signal(SIGALRM, sigalrm);
/*切換工做目錄*/
chroot(HTTPD_DOCUMENT_ROOT);
printf("starting httpd...\n");
printf("press q to quit.\n");
// chdir("/");
/*第二步,輸入命令並進行處理*/
if (argc > 1 && !strcmp(argv[1], "-i")) {
/* I'm running from inetd, handle the request on stdin */
fclose(stderr);
HandleConnect(0);
exit(0);
}
/*第三步,創建socket接口*/
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
perror("Unable to obtain network");
exit(1);
}
if((setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&true,
sizeof(true))) == -1) {
perror("setsockopt failed");
exit(1);
}
/*定義server_sockaddr結構體中的內容*/
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(SERVER_PORT);
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
/*第四步,對端口和地址進行綁定*/
if(bind(s, (struct sockaddr *)&server_sockaddr,
sizeof(server_sockaddr)) == -1) {
perror("Unable to bind socket");
exit(1);
}
/*第五步,監聽端口*/
if(listen(s, 8*3) == -1) { /* Arbitrary, 8 files/page, 3 clients */
perror("Unable to listen");
exit(4);
}
/*第六步,多線程建立,等待鏈接*/
pthread_create(&th_key, NULL, key, 0);
/* Wait until producer and consumer finish. */
printf("wait for connection.\n");
while (1) {
len = sizeof(ec);
/*第七步,接收客戶端鏈接請求*/
if((fd = accept(s, (void *)&ec, &len)) == -1) {
exit(5);
close(s);
}
HandleConnect(fd);
}
/*第八步,等待線程鏈接結束以後再結束main函數*/
pthread_join(th_key, &retval);
}
二、編譯應用程序
先修改了Makefile:
而後運行make產生可執行文件httpd
三、下載調試
使用 NFS 服務方式將 HTTPD 下載到開發板上,並拷貝測試用的網頁進行調試
在超級終端輸入以下代碼
四、本機測試
在臺式機的瀏覽器中輸入 http://192.168.0.121
(/192.168.0.121 爲 UP-CUP S2410 實驗板的 IP 地址)
實驗總結:
此次實驗仍是使用124實驗的實驗環境,配置環境很順利,開始進行make編譯的時候出錯,用實驗4中的方法在/usr/src 下沒有創建一個linux 鏈接,以後更改了一下Makefile的配置,就能夠順利編譯了,以後超級終端的掛載都很順利。
此次實驗的體會是,不必定要全按指導書上的內容,好比Makefile的配置,掛載時的文件目錄都要根據實際狀況進行更改,才能實驗成功。