2010-11-22 154 views
2

你好,我正在嘗試使我想要這些東西的TCP客戶端/服務器。 客戶端將給出文件名或文件的文件名路徑。 服務器將找到該文件並提供以下詳細信息: 權限,大小,所有者,所有者組,修改/創建日期,單詞數量,用戶標識和優先級,如果發生錯誤,則將這些文件發送到-1的客戶端。客戶端將打印這些細節。我已經做了很多這些事情,但我有一個巨大的問題,所以我不能繼續,我的問題是,服務器無法識別文件的路徑,但我試圖命名文件和通信它OK.What我我做錯了嗎? 預先感謝您你如何傳遞從客戶端到服務器的路徑?

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

     void error(char *msg) 
     { 
      perror(msg); 
      exit(0); 
     } 

     int main(int argc, char *argv[]) 
     { 
      int sockfd, portno, n; 
      struct sockaddr_in serv_addr; 
      struct hostent *server; 

      char buffer[1024]; 
      if (argc < 3) { 
       fprintf(stderr,"usage %s hostname port\n", argv[0]); 
       exit(0); 
      } 
      portno = atoi(argv[2]); 
      sockfd = socket(AF_INET, SOCK_STREAM, 0); 
      if (sockfd < 0) 
       error("ERROR opening socket"); 
      server = gethostbyname(argv[1]); 
      if (server == NULL) { 
       fprintf(stderr,"ERROR, no such host\n"); 
       exit(0); 
      } 
      bzero((char *) &serv_addr, sizeof(serv_addr)); 
      serv_addr.sin_family = AF_INET; 
      bcopy((char *)server->h_addr, 
       (char *)&serv_addr.sin_addr.s_addr, 
       server->h_length); 
      serv_addr.sin_port = htons(portno); 
      if (connect(sockfd,&serv_addr,sizeof(serv_addr)) < 0) 
       error("ERROR connecting"); 
      printf("Please enter the filename or path of filename: "); 
      bzero(buffer,1024); 
      fgets(buffer,1024,stdin); 
      n = write(sockfd,buffer,strlen(buffer)); 
      if (n < 0) 
       error("ERROR writing to socket"); 
      bzero(buffer,1024); 
      n = read(sockfd,buffer,1024); 
      if (n < 0) 
       error("ERROR reading from socket"); 
      printf("%s\n",buffer); 
      return 0; 



SERVER 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <sys/resource.h> 
#include <sys/time.h> 

void error(char *msg) 
{ 
    perror(msg); 
    exit(1); 
} 

int main(int argc, char *argv[]) 
{  
    FILE *fp; 
    int sockfd, newsockfd, portno, clilen,i; 
    char buffer[1024],filename[1024]; 
    char * pPath; 
    struct sockaddr_in serv_addr, cli_addr; 
    int n; 
    int which = PRIO_PROCESS; 
    id_t pid; 
    int ret; 
    if (argc < 2) { 
     fprintf(stderr,"ERROR, no port provided\n"); 
     exit(1); 
    } 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if (sockfd < 0) 
     error("ERROR opening socket"); 
    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    portno = atoi(argv[1]); 
    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_addr.s_addr = INADDR_ANY; 
    serv_addr.sin_port = htons(portno); 
    if (bind(sockfd, (struct sockaddr *) &serv_addr, 
       sizeof(serv_addr)) < 0) 
       error("ERROR on binding"); 
    listen(sockfd,5); 
    clilen = sizeof(cli_addr); 
    newsockfd = accept(sockfd, 
       (struct sockaddr *) &cli_addr, 
       &clilen); 
    if (newsockfd < 0) 
      error("ERROR on accept"); 
    bzero(buffer,1024); 
    n = read(newsockfd,buffer,1024); 
    if (n < 0) error("ERROR reading from socket"); 
    printf("Here is the message: %s\n",buffer); 

    system("ls -al 1.txt > ls.txt"); 
    system("wc -w 1.txt > wc.txt"); 



    /* pPath = getenv ("PATH"); 
    if (pPath!=NULL) 
    printf ("The current path is: %s\n",pPath); 

    system("touch path.txt"); 
    fp=fopen("path.txt","w"); 
     if (fp==NULL) exit(1); 
fprintf(fp,pPath); 
    fclose(fp); */ 


    pid = getpid(); 
    ret = getpriority(which, pid); 
    printf("priority %d user id %d ret %d",which,pid,ret); 

system("paste ls.txt wc.txt user.txt > info.txt"); 

    fp=fopen("info.txt","r"); 

    if (fp==NULL) exit(1); 

    for(int i=0;i<1000;i++){ 

      fscanf(fp,"%c",&buffer[i]); 
    } 
    fclose(fp);   

    n = write(newsockfd,buffer,1024); 
    if (n < 0) error("ERROR writing to socket"); 
    return 0; 
} 
    }` 

謝謝你的快速reply.To具體,教授也沒問我們做出這個txt文件我創建的,但我創建因爲我無法找到一個解決方案我寫不出一切buffer.It應該是這樣的:

緩衝層i與路徑來從客戶 查找路徑文件從緩存(這是我有問題) LS -al寫緩衝(我寫到.txt) wc寫入緩衝區(我寫到.txt) 路寫入緩存(還沒有這樣做還) 用戶信息寫入到緩存(還沒有這樣做還) 緩衝發送到客戶端 打印所有這些信息緩衝

我嘗試sprintf的,但我沒不明白你是怎麼使用它的,但是這個命令看起來比我的好謝謝:)。如果我理解的很好,否則通過緩衝區。

回答

0

您可能需要將路徑傳遞到您的系統調用中。分配一個緩衝區(記住你應該對緩衝區進行檢查以確保安全,但我理解這可能是家庭作業)並使用sprintf(http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/) :

char lsbuf[1024]; 
sprintf(lsbuf,"ls -al %s > ls.txt",buffer); 
system(lsbuf); 

正確的方法做事情(和你的老師最有可能想讓你做他們的方式)是做LS,廁所等內碼的工作。像這樣的調用系統會讓您面對全新的安全漏洞。

+1

是的,例如,如果文件名包含「; rm -rf *;」,系統調用會發生什麼情況。 – buddhabrot 2010-11-22 09:19:05

0

傳遞給服務器的路徑是否包含尾隨的'\ n'?如果是這樣,你應該刪除它(例如通過放置\ 0字符)

0

在您當前的代碼中,沒有真正與客戶端的輸入有關,並且行爲與您的描述不匹配。
這是什麼應該做的?:

for(int i=0;i<1000;i++){ 
     fscanf(fp,"%c",&buffer[i]); 
    } 
    fclose(fp);  

這將尋找在輸入每個字符(如看你用1000這裏,緩衝器可爲1024個字符,你缺少最後的24個字符)並返回「info.txt」中出現的次數。請注意,您還將搜索NUL字符('\ 0')。除了這些粗心大意之外,它並沒有真正做任何事情。

我假設你只是想找到文件中的字符串,並使用行號?你需要一個不同的搜索字符串的方法。有一些聰明和不那麼聰明的算法。其中一個比較「野蠻」的算法是:

  1. 搜索的第一個字符
  2. 保留一些標誌爲「真」,只要所有的下一字符符合預期的字符
  3. 如果某些字符違反了比賽,請轉到下一個搜索的第一個字符

請注意,有比這更高效的算法。

我沒有仔細檢查您的網絡設置,假設它有效。將代碼分成若干段使用更多空格,或將網絡設置置於不同的功能將是一個好主意。

0

首先,應該避免使用bzero,因爲該函數已被棄用。改用memset。

函數fgets讀取直到換行符或文件結束達到。由於換行符是一個有效的字符,因此將其添加到字符串中並添加空字符。

如果您輸入「mytext」,然後輸入,則緩衝區將具有「mytext \ n \ 0」。

根據當前的代碼,你甚至沒有使用客戶端的緩衝區,所以很明顯它不起作用(不是因爲附加的換行符導致的fgets()行爲)。

0

對不起,回答這樣的,但我沒有一個帳戶,我是新來的(我沒有問題,我的項目,4年:P)。我插入

char lsbuf[1024]; 
sprintf(lsbuf,"ls -al %s > ls.txt",buffer); 
system(lsbuf); 

和幾乎像一個魅力工作...它接受路徑和做ls但不保存ls到ls.txt(創建空文件),並不會將其發送到緩衝區。此外我試着將memset和工作中!!

相關問題