Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unix客户端和服务器在向客户端读取文件后陷入无限循环_Unix_Client - Fatal编程技术网

Unix客户端和服务器在向客户端读取文件后陷入无限循环

Unix客户端和服务器在向客户端读取文件后陷入无限循环,unix,client,Unix,Client,我目前正在制作一个简单的客户端和服务器,但我遇到了一个问题。系统的一部分用于客户端查询服务器上的本地文件。然后必须将该文件的内容发送到客户端。我能够将文件中的所有文本发送到客户端,但它似乎卡在客户端的读取循环中。以下是用于处理此问题的客户端和服务器的代码: 读取循环的客户端代码 else if(strcmp(commandCopy, get) == 0) { char *ptr; int total = 0;

我目前正在制作一个简单的客户端和服务器,但我遇到了一个问题。系统的一部分用于客户端查询服务器上的本地文件。然后必须将该文件的内容发送到客户端。我能够将文件中的所有文本发送到客户端,但它似乎卡在客户端的读取循环中。以下是用于处理此问题的客户端和服务器的代码:

读取循环的客户端代码

 else if(strcmp(commandCopy, get) == 0)
        {

            char *ptr;
            int total = 0;
            char *arguments[1024];
            char copy[2000];
            char * temp;
            int rc;

            strcpy(copy, command);

            ptr = strtok(copy," ");

            while (ptr != NULL)
            {
                temp = (char *)malloc(sizeof(ptr));
                temp = ptr;
                arguments[total] = temp;
                total++;
                ptr = strtok (NULL, " ");
            }

            if(total == 4)
            {
                if (strcmp(arguments[2], "-f") == 0)
                {
                    printf("1111111111111");
                    send(sockfd, command, sizeof(command), 0 );
                    printf("sent %s\n", command);
                    memset(&command, '\0', sizeof(command));

                    cc = recv(sockfd, command, 2000, 0);
                    if (cc == 0)
                    {
                        exit(0);
                    }

                }
                else
                {
                    printf("Here");
                    strcpy(command, "a");
                    send(sockfd, command, sizeof(command), 0 );
                    printf("sent %s\n", command);
                    memset(&command, '\0', sizeof(command));

                    cc = recv(sockfd, command, 2000, 0);
                }
            }
            else
            {
                send(sockfd, command, sizeof(command), 0 );
                printf("sent %s\n", command);
                memset(&command, '\0', sizeof(command));

                while ((rc = read(sockfd, command, 1000)) > 0) 
                {
                    printf("%s", command);
                }

                if (rc)
                    perror("read");
            }



        }
读取文件的服务器代码

char* getRequest(char buf[], int fd)
{

    char * ptr;
    char results[1000];
    int total = 0;
    char *arguments[1024]; 
    char data[100];

    FILE * pFile;
    pFile = fopen("test.txt", "r");

    ptr = strtok(buf," ");

    while (ptr != NULL)
    {
        char * temp; 
        temp = (char *)malloc(sizeof(ptr));
        temp = ptr;
        arguments[total] = temp;
        total++;
        ptr = strtok (NULL, " ");
    }

    if(total < 2)
    {
        strcpy(results, "Invaild Arguments \n");
        return results;
    }

    if(pFile != NULL)
    {
        while(fgets(results, sizeof(results), pFile) != NULL)
        {
            //fputs(mystring, fd);
            write(fd,results,strlen(results));
        }
    }
    else
    {
        printf("Invalid File or Address \n");
    }
    fclose(pFile);
    return "End of File \0";
}

主要的问题似乎是服务器发送了所有的内容,但它没有关闭套接字,因此客户端无法知道服务器已经完成了。如果在完成数据发送后关闭套接字(或只调用shutdown()),则客户端的read()在完成数据读取后将返回0

FWIW,此代码还有很多其他问题:

  • getRequest:你打电话给malloc,但从不免费。事实上,返回值被丢弃了
  • 如果你只是想照顾孩子,为什么还要费心用叉子叉
  • 您可能希望使用strlcpy而不是strpcy来避免缓冲区溢出

客户端代码中的整个
else if
子句对于函数来说有点大,更不用说函数的一部分了。代码中的逻辑是。。。有趣。让我们剖析第一部分:

else if (strcmp(commandCopy, get) == 0)
{
    char *ptr;
    int total = 0;
    char *arguments[1024];
    char *temp;

    ptr = strtok(copy, " ");

    while (ptr != NULL)
    {
        temp = (char *)malloc(sizeof(ptr));
        temp = ptr;
        arguments[total] = temp;
        total++;
        ptr = strtok(NULL, " ");
    }
我已经删除了非实质性声明和一些代码。在上下文中使用strtok()是可以的,但是内存分配是泄漏的。为字符指针分配足够的空间,然后将指针从
strtok()
复制到分配空间的唯一指针上(从而泄漏它)。然后指针被复制到
参数[total]
。因此,该守则可简化为:

else if (strcmp(commandCopy, get) == 0)
{
    char *ptr;
    int total = 0;
    char *arguments[1024];

    ptr = strtok(copy, " ");

    while (ptr != NULL)
    {
        arguments[total++] = ptr;
        ptr = strtok(NULL, " ");
    }
名义上,应该检查
参数列表是否溢出,但由于原始设置将字符串限制为2000个字符,因此参数不能超过1000个(所有单个字符由单个空格分隔)


您所拥有的功能—它在很长的一段时间内实现了相同的赋值,但它会极大地泄漏内存。

为什么不先发送文件大小(二进制)来简化代码?然后您可以只进行一次读取,或者至少知道您应该期望的内容。为什么不“插入”您的代码以发出调试/跟踪信息,这样您就可以确切地看到是哪个块导致了问题。那么就很容易弄清楚为什么会这样。此外,如果您确定是“客户端读取”导致了循环,请确认通过从图片中删除服务器,通过注释套接字内容,如果完成,则与套接字的处理有关,如果继续无限循环,则需要查看如何读取文件。祝你好运
else if (strcmp(commandCopy, get) == 0)
{
    char *ptr;
    int total = 0;
    char *arguments[1024];

    ptr = strtok(copy, " ");

    while (ptr != NULL)
    {
        arguments[total++] = ptr;
        ptr = strtok(NULL, " ");
    }