2

您好,我正在尝试制作一个我想要这些东西的 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 文件,但我创建的原因是我找不到解决方案,我无法将所有内容写入缓冲区。应该是这样的:

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

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

4

5 回答 5

0

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

于 2010-11-22T09:14:36.223 回答
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. 如果某些字符违反匹配,则转到第一个字符的下一个搜索

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

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

于 2010-11-22T09:18:20.767 回答
0

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

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

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

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

于 2010-11-22T09:18:53.570 回答
0

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

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

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

于 2010-11-22T12:06:53.547 回答
0

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

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

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

于 2010-11-22T09:13:05.523 回答