【问题标题】:How you pass path from client to server?您如何将路径从客户端传递到服务器?
【发布时间】:2011-10-03 01:12:06
【问题描述】:

您好,我正在尝试制作一个我想要这些东西的 TCP 客户端/服务器。 客户端将给出文件的文件名或文件名的路径。 服务器将找到该文件并提供以下详细信息: 权限、大小、所有者、所有者组、修改/创建日期、字数、用户 ID 和优先级,如果出现问题,将这些发送给 -1 的客户端。客户端将打印该详细信息。我做了很多这件事,但我有一个很大的问题,所以我不能继续,我的问题是服务器无法识别文件的路径,但我尝试命名文件并通信正常。我做错了什么? 提前谢谢你

    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; 
}
    }`

感谢您的快速回复。具体来说,教授没有要求我们制作我创建的这个 txt 文件,但我创建的原因是我找不到解决方案,我无法将所有内容写入缓冲区。应该像这样:

缓冲区 i 来自客户端的路径 从缓冲区中找到路径文件(这是我有问题的地方) ls -al 写入缓冲区(我将其写入 .txt) wc 写入缓冲区(我将其写入 .txt) 写入缓冲区的路径(尚未完成) 用户信息写入缓冲区(还没有这样做) 缓冲区发送到客户端 客户端使用所有这些信息打印缓冲区

我尝试了 sprintf,但我不明白你是如何使用它的,但是这个命令看起来比我的要好,谢谢:)。如果我理解得很好,则不会通过缓冲区。

【问题讨论】:

    标签: c tcpclient tcpserver


    【解决方案1】:

    您可能需要将路径传递给您的系统调用。分配一个缓冲区(请记住,您应该检查缓冲区的安全性,但我知道这可能是家庭作业)并使用 sprintf(http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/) :

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

    做事的正确方式(以及你的导师最可能希望你做的方式)是在代码中完成 ls、wc 等的工作。像这样的调用系统会让您面临全新的安全漏洞。

    【讨论】:

    • 是的,例如,如果文件名包含“;rm -rf *;”,请考虑系统调用中会发生什么
    【解决方案2】:

    传递给服务器的路径是否包含尾随'\n'?如果是这样,您应该删除它(例如通过放置 \0 字符)

    【讨论】:

      【解决方案3】:

      在您当前的代码中,客户端的输入实际上并没有做任何事情,并且行为与您对它的描述不匹配。
      这是做什么的?:

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

      这将查找输入中的每个字符(当您在此处使用 1000,并且缓冲区可以是 1024 个字符,您缺少最后 24 个字符)并返回它在“info.txt”中出现的次数。请注意,您还将搜索 NUL 字符 ('\0')。除了这些粗心之外,它并没有真正做任何事情。

      我假设您只想在文件中查找字符串,并使用行号?您需要一种不同的搜索字符串的方法。有一些聪明和不那么聪明的算法。比较“粗暴”的算法之一是:

      1. 搜索第一个字符
      2. 只要所有下一个字符都与预期字符匹配,就将某些标志保持为“真”
      3. 如果某个字符违反了匹配,则转到下一个搜索第一个字符

      请注意,还有比这更有效的算法。

      我没有仔细检查您的网络设置,假设它有效。使用更多的空格将代码分成几段,或者将网络设置放入不同的函数中,这将是一个好主意。

      【讨论】:

        【解决方案4】:

        首先,应避免使用 bzero,因为该函数已被弃用。请改用 memset。

        函数 fgets 读取,直到到达换行符或文件结尾。由于换行符是有效字符,因此将其添加到字符串中并附加一个空字符。

        如果你输入“mytext”然后输入,缓冲区将有“mytext\n\0”。

        根据当前代码,您甚至没有使用来自客户端的缓冲区,因此很明显它不起作用(不是因为附加换行符导致的 fgets() 行为)。

        【讨论】:

          【解决方案5】:

          很抱歉这样回复,但我没有帐户,我是新手(我的项目 4 年没有问题:P)。我插入

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

          并且几乎像魅力一样工作...它接受路径并执行 ls 但不将 ls 保存到 ls.txt(创建空文件)并且不将其发送到缓冲区。我也尝试替换 memset 并且正在工作!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-02-16
            • 2016-11-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多