這次這個軟體仍然是用C編的,可以在linux環境下實現:下載文檔,編輯文檔,關閉遠程主機,重新啟動遠程主機,修改管理員密碼這五個功能.
由於編程只是本人的業餘愛好,水平實在有限,所以軟體做的比較垃圾,希望各位高手不吝賜教
此軟體只能在linux環境下運行.
伺服器實現的關鍵代碼如下:
int main(int argc, char** argv)
//argc為參數的個數,argv[0]對應程式, argv[1]對應-p, argv[2]對應連接埠號碼
{
………………………………
if (argc != 3 || strcmp(argv[1], "-p") || (port = atoi(argv[2])) < 1024) {
//argc不為0,或argv[1]不為-p,或連接埠號碼<1024,則退出
………………………………
}
if (uname(&myname) < 0 || (he = gethostbyname(myname.nodename)) == NULL) {
//獲得主機名稱
………………………………
}
hostaddr = *(unsigned long *)(he->h_addr);
listen_fd = init_socket(port);
//初始化通訊端,建立,綁定並監聽socket
if ((p = strrchr(argv[0], '/')) != NULL)
//取得”/”最後一次出現處到結尾的字串,即程式名,賦值給p
p ++;
else
p = argv[0];
//如果p為NULL,則argv[0]就是程式名, 賦值給p
sprintf(root_path, "/app/%s", p); //路徑:app下的程式名
p = argv[0] + strlen(argv[0]) - 1;
while (*p && *p != '/') {
*p = toupper(*p); //將字元轉化為大寫英文字元
p --;
}
daemon( 1, 1 ); //精靈
syslog(LOG_ERR, "*** Starting %s on %s ***", p + 1, inet_ntoa(*(struct in_addr *)&hostaddr)); //在系統日誌中寫入相關資訊
………………………………
for (;;) {
FD_ZERO( &afdset );
//afdset為檔案描述符集,現清空afdset與所有檔案控制代碼的聯絡。
maxfd = -1;
FD_SET( listen_fd, &afdset ); //加入通訊端
if ( listen_fd > maxfd )
maxfd = listen_fd; //將maxfd的值始終保持最大值
if (select(maxfd + 1, &afdset , NULL, NULL, NULL) < 0)
continue;
………………………………
if (FD_ISSET( listen_fd, &afdset ) )
conn_fd = accept( listen_fd, (struct sockaddr *)&usa, &sz );
//傳回值 成功:返回最後的伺服器端的檔案描述符,這個時候伺服器端可以向該描述符寫資訊了。即 conn_fd = listen_fd。
失敗:返回-1。即conn_fd = -1。
else
continue;
………………………………
if ((r = fork()) < 0 ) {
//fork( )的主要任務是初始化要建立進程的資料結構. 當fork()!=0 的時候,表明是父進程,要終止
………………………………
} else if ( r == 0 ) {
//當fork()==0 的時候,表明是子進程,執行
client_addr = usa;
close( listen_fd );
//將套介面做上“已關閉的標記”,並立即返回進程
get_http(); //通過該函數獲得HTTP協議的要求方法,並調用do_cgi()
exit( 0 );
}
close( conn_fd );
}
}
下載文檔功能實在的關鍵代碼如下:
my_cgi()
{………………………………
else if (strcmp(p, "download") == 0)
//判斷表單變數,如果是download則運行down_load函數
down_load(); //顯示下載文檔介面,並指定對示範文檔的操作方式
………………………………
}
static down_load()
{………………………………
if ((p = getenv("PATH_INFO")) == NULL ||
strncmp(p, "/demo/", 6) != 0) {
disp_file_menu(0);
//通過判斷路徑資訊和文檔資訊,調用disp_file_menu(0),參數0表示出現下載文檔介面
return;
}
if ((fp = fopen(fn, "r")) != NULL) { // fopen(fn, "r")表示以唯讀方式開啟檔案fn
while ((i = fread(buf, 1, 4096, fp)) > 0)
fwrite(buf, 1, i, stdout);
fclose(fp); //對所選擇的文檔進行下載
………………………………
}
編輯文檔功能實現的關鍵代碼如下:
void edit_file()
{ ………………………………
disp_file_menu(1);
//通過判斷路徑資訊和文檔資訊,調用disp_file_menu(1),參數1表示出現編輯文檔介面
………………………………
disp_edit_file(0);
//對文檔的狀態進行判斷,當參數為1,3,9分別執行相應動作,其它參數則不執行動作
………………………………
disp_edit_file(1); //參數為1,返回”主機串連失敗”
………………………………
disp_edit_file(9); //參數為9,返回”檔案修改成功”
………………………………
}
void disp_edit_file(int type)
{………………………………
printf("<script language="javascript"> ");
printf("function thisform_OnSubmit() ");
//修改文檔後,按下“確定”按鈕執行javascript指令碼程式,儲存修改後的文檔
printf("{ ");
printf(" return confirm("儲存修改後的文檔嗎?"); ");
printf("} ");
printf("</script> ");
………………………………
if (type == 1) //針對不同的type值返回不同的反饋資訊
printf("<p align="center"><strong><font color="#FF0000">主機串連失敗!</font></strong></p> ");
else if (type == 3)
………………………………
else if (type == 9)
………………………………
}
關閉遠程主機功能實現的關鍵代碼如下:
void host_stop()
{
if (get_form("stat") == NULL) {
disp_host_control_hoststop(); //顯示關閉主機介面
return;
}
execlp("init", "init", "0", 0); //將execlp的第三個參數設定為0,遠程關閉主機
重新啟動遠程主機功能實現的關鍵代碼如下:
void host_restart()
{
if (get_form("stat") == NULL) {
disp_host_control_hostrestart(); //顯示暖開機主機介面
return;
}
execlp("init", "init", "6", 0); //將execlp的第三個參數設定為6,重新啟動系統
}