开发者

Unix Client and Server Stuck in an Infinite Loop After Reading a File to the Client

I am currently making a simple client and server but I have run into an issue. Part of the system is for the client to query about a local file on the server. The contents of that file must be then sent to the client. I am able to send all the text within a file to the client however it seems to be stuck in the read loop on the client. Below are the code spits for both the client and server that are meant to deal with this:

Client Code That Reads The Loop

 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(so开发者_如何学运维ckfd, 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");
            }



        }

Server Code That Reads the File

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

Server Code to execute the command

else if(strcmp(command, "get") == 0)
{
    int pid = fork();
    if (pid ==-1) 
    {
        printf("Failed To Fork...\n");
        return-1;
    }
    if (pid !=0)
    {
       wait(NULL);

    }
    else
    {

       char* temp;
       temp = getRequest(buf, newsockfd);

       strcpy(buf, temp);

       send(newsockfd, buf, sizeof(buf), 0 );
       exit(1);
    }

}


The whole else if clause in the client code is a bit large for a function, let alone a part of a function as it presumably is. The logic in the code is ... interesting. Let us dissect the first section:

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, " ");
    }

I've removed immaterial declarations and some code. The use of strtok() is fine in context, but the memory allocation is leaky. You allocate enough space for a character pointer, and then copy the pointer from strtok() over the only pointer to the allocated space (thus leaking it). Then the pointer is copied to arguments[total]. The code could, therefore, be simplified to:

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, " ");
    }

Nominally, there should be a check that you don't overflow the arguments list, but since the original limits the string to 2000 characters, you can't have more than 1000 arguments (all single characters separated by single spaces).

What you have works - it achieves the same assignment the long way around, but it leaks memory prodigiously.


The main problem seems to be that the server sends all the contents, but it doesn't close the socket, so the client has no way of knowing the server's done. If you close the socket after you finish sending the data (or just call shutdown()), then the client's read() will return 0 when it finishes reading the data.

FWIW, there are lots of other problems with this code:

  • getRequest: you call malloc but never free. In fact, the return value is thrown away.
  • Why bother forking if you're just going to wait() on the child?
  • You probably want to use strlcpy instead of strpcy to avoid buffer overruns.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜