遠程訪問服務器目錄

1、設計
三個需要:
(1).協議
(2)客戶端程序
(3)服務器端程序
2、協議
協議包含有請求和應答。首先,客戶端發送一行包含有目錄名稱的請求。服務器讀取該目錄名之後打開並讀取該目錄,然後把文件列表發送到客戶端。客戶端循環地讀取文件列表,直到服務器掛斷連接產生文件結尾標誌。
3、 客戶端程序

#include<stdio.h>
#include<sys/types.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<unistd.h>
#include<stdlib.h>
#include<arpa/inet.h>

#define oops(msg) {perror(msg);exit(1);}
#define PORTNUM 15000

int main(int argc,char *argv[])
{
  struct sockaddr_in servaddr;
  int sock_id;
  char buff[BUFSIZ];
  int n_read;

  if(argc != 2)exit(1);
  sock_id = socket(AF_INET,SOCK_STREAM,0);

  if(sock_id == -1)
    oops("socket creat perror");

  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(PORTNUM);
  servaddr.sin_addr.s_addr = inet_addr("192.168.1.127");

  if(connect(sock_id,(struct sockaddr*)&servaddr,sizeof(servaddr))!=0)
    oops("connect error");

  if(write(sock_id,argv[1],strlen(argv[1])) == -1)
    oops("write error");

  if(write(sock_id,"\n",1) == -1)
    oops("write error2");

  while((n_read = (int)read(sock_id,buff,BUFSIZ))>0)
  {
    if(write(1,buff,(size_t)n_read) == -1)
      oops("printf error");
    close(sock_id);
  }
  return 0;
}   

4、服務器端程序

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<time.h>
#include<strings.h>
#include<string.h>
#include<arpa/inet.h>
#include<ctype.h>

#define PORTNUM 15000
#define HOSTLEN 256
#define oops(msg) {perror(msg);exit(1);}
void sanitize(char *str)
{   
  char *src,*dest;
  for(src = dest = str;*src;src++)
    if(*src == '/'|| isalnum(*src))
      *dest++ = *src;

  *dest = '\0';
}   

int main()  
{
  struct sockaddr_in saddr;
  int sock_id,sock_fd;
  FILE *sock_fpi,*sock_fpo;
  FILE *pipe_fp;
  char dirname[BUFSIZ];
  char command[BUFSIZ];
  int c;

  sock_id = socket(PF_INET,SOCK_STREAM,0);
  if(sock_id == -1)
    oops("socket");

  saddr.sin_family = AF_INET;
  saddr.sin_port = htons(PORTNUM);
  saddr.sin_addr.s_addr = inet_addr("192.168.1.127");

  if(bind(sock_id,(struct sockaddr*)&saddr,sizeof(saddr))!=0)
    oops("bind error");

  if(listen(sock_id,1) != 0)
    oops("listen error");

  while(1)
  {
    sock_fd = accept(sock_id,NULL,NULL);

    if(sock_fd  == -1)
      oops("accept error");

    if((sock_fpi = fdopen(sock_fd,"r")) == NULL)
      oops("fdopen reading");

    if(fgets(dirname,BUFSIZ-5,sock_fpi) == NULL)
      oops("reading dirname");

    sanitize(dirname);

    if((sock_fpo = fdopen(sock_fd,"w")) == NULL)
      oops("fdopen write");

    sprintf(command,"ls %s",dirname);
    if((pipe_fp = popen(command,"r")) == NULL)

      oops("popen");

    while((c = getc(pipe_fp))!=EOF)
      putc(c,sock_fpo);

    pclose(pipe_fp);
    pclose(sock_fpo);
    pclose(sock_fpi);
  }
  return 0;
}   

服務器程序使用標準緩存流來讀寫數據。服務器用 fgets 調用從客戶端讀取目錄
名。在調用 popen 後,服務器就像複製文件一樣地使用 getc 和 putc 來傳輸數據。當然,服務器實際上是從本機上的進程向另一臺機器上的進程複製數據。

**************************************************************************************對於任何運行參數中所含的命令或從因特網上獲取數據的服務器,在編寫的時候都要格外小心。程序中的服務器等待接收來自客戶端的目錄名,然後把它追加到 Is 命令的尾部如果有人發送字符串 “;rm “給服務器,服務器將創建並運行 “ls ; rm “命令了。爲了減少被破壞的風險,程序中必須確保接收的字符串沒有溢出輸入緩存,也沒有溢出給命令設置的緩存並且接收的目錄名中不允許出現非法字符。 popen 系統調用對於編寫網絡服務來說是很危險的,因爲它直接把-行字符串傳給 shell 。在網絡程序中,將字符串傳給shell 是一個非常錯誤的想法。*


軟件精靈:
Unix 服務器程序有短小、簡潔的名字。很多服務器程序都是以d 結尾,如 httpd 、 inetd 、 syslogd 和 atd 。這裏的 d 表示精靈 (daemon) 的意思,因而如名叫syslogd 的服務器程序實際上是系統日誌精靈 (system log daemon) 。精靈就是一個爲他人
提供服務的幫助者,它隨時等待去幫助別人。輸入命令 ps -el 或 ps -ax 就可以看到以字符 d 結尾的進程。然後,可以去閱讀這些命令的幫助信息,從而可以更加深入地理解 Unix 中用客戶/服務器模型是如何來處理一些基礎操作的。大部分精靈進程都是在系統啓動後就處於運行狀態了。位於類似於 /etc/rc. d 目錄中的 shell 腳本在後臺啓動了這些服務,它們的運行與終端相分離,時刻準備提供數據或服務。

總結:
•一些程序被作爲單獨的進程建立起來來接收和發送數據。在客戶/服務器模型中,服務器進程爲客戶進程提供處理或數據服務。
•客戶/服務器系統包含通信系統和協議。客戶和服務器通過管道或 socket 進行通信。協議是會話過程中-系列規則的集合。
• popen 庫函數可以將任何 shell 程序嵌入服務器程序並且讓對服務器的訪問就像訪問緩存文件一樣。
•管道是-對相連接的文件描述符。 socket 是一個未連接的通信端點,也是一個潛在
的文件描述符。客戶進程通過把自己的 socket 和服務器端的 socket 相連來創建一
個通信連接。
• sockets 之間的連接可以擴展到另一臺機器上。每個 socket 以機器地址和端口來
標識。
•到管道和 socket 的連接使用文件描述符。文件描述符爲程序提供了與文件、設備和其他的進程通信的統一編程接口。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章