Разъем C: recv блокирует программу, если используется дважды - PullRequest
0 голосов
/ 02 декабря 2018

Я пытаюсь внедрить AC-код на платформе UNIX, который отправляет все данные файлов клиенту, и загружает файл с клиента на сервер.

Первая часть работает, но для второйчасть я столкнулся с проблемой.После некоторой отладки я обнаружил, что серверная сторона блокирует клиента, когда я использую recv во второй раз в коде [я отметил это для вашего удобства].

Я пытался посмотретьв руководствах или что я делаю не так, но я не смог найти проблему, из-за которой программа зависла.

В целях устранения ошибок я сейчас пытаюсь отправить intот клиента к серверу

на стороне сервера

   #include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <dirent.h>
#include <fcntl.h>

#define PORT 0x0da2
#define IP_ADDR 0x7f000001
#define QUEUE_LEN 20

int main(void)
{
    //char directory[1024];
    //chdir("server");
    //getcwd(directory, sizeof(directory));
    //printf("%s",directory);
    DIR* directory;
    struct dirent* ent;
    int fd;
    char buffer[1000] = {0};
    char convert[100] = {0};
    size_t array_size = 0;
    struct stat fileStat;
    if ((directory = opendir ("server")) == NULL) 
    {
            perror ("Cannot open .");
            return 1;
        }

    while ((ent = readdir(directory)) != NULL) 
    {

        if (!( !strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) )
        {
            fd = openat(dirfd(directory), ent->d_name, 0);

            if (fd == -1)
            {
                perror ("Can't get stats.");
                return 1;
                }   

            if(fstat(fd, &fileStat)== -1)
            {
                perror ("Can't get stats.");
                return 1;
                }
            strcat(buffer,ent->d_name);
            sprintf(convert,"%lld", (long long) fileStat.st_size);
            strcat(buffer, " ");
            strcat(buffer,convert);
            strcat(buffer,"\n");

        }
        }

    int listenS = socket(AF_INET, SOCK_STREAM, 0);

    if (listenS < 0)
    {
        perror("socket");
        return 1;
    }

    struct sockaddr_in s = {0};
    s.sin_family = AF_INET;
    s.sin_port = htons(PORT);
    s.sin_addr.s_addr = htonl(IP_ADDR);

    if (bind(listenS, (struct sockaddr*)&s, sizeof(s)) < 0)
    {
        perror("bind");
        return 1;
    }

    if (listen(listenS, QUEUE_LEN) < 0)
    {
        perror("listen");
        return 1;
    }

    struct sockaddr_in clientIn;
    int clientInSize = sizeof clientIn;

    while (1)
    {
        int newfd = accept(listenS, (struct sockaddr*)&clientIn, (socklen_t*)&clientInSize);

        if (newfd < 0)
        {
            perror("accept");
            return 1;
        }

        if (send(newfd, &buffer, strlen(buffer), 0) < 0)
        {
            perror("send");
            return 1;
        }

        char namebuff[100] = {0};
        char sizebuff[256] = {0};
        //int size;
        ssize_t nrecv;
        int error = 0;
        int fsize;
        //int dataleft;

        if ((nrecv = recv(newfd, &namebuff, sizeof(namebuff), 0)) < 0)
        {
        perror("recv");
        return 1;
        }

        if((strstr(buffer,namebuff) != NULL))
        {
                error = -1;

                if (send(newfd, &error, sizeof(int), 0) < 0)
                {
                    perror("send");
                    return 1;
                }

        }

        /*if ((nrecv = recv(newfd, &fsize, sizeof(int), 0)) < 0) //this line is what jams the program
            {
            perror("recv");
            return 1;
            }*/

        if(error != -1) // 
        {

            if ((nrecv = recv(newfd, &sizebuff, sizeof(sizebuff), 0)) < 0)
            {
            perror("recv");
            return 1;
            }

        fsize = atoi(sizebuff);
        }


        printf("%s\n",namebuff);
        printf("%d\n",fsize);
        close(newfd);
    }
    close(listenS);

    return 0;
}

на стороне клиента

    #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <fcntl.h>
#define PORT 0x0da2
#define IP_ADDR 0x7f000001
int ctoi(char c) {

    return c-'0';

}


int main(void)
{
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    ssize_t nrecv;
    struct sockaddr_in s = {0};
    s.sin_family = AF_INET;
    s.sin_port = htons(PORT);
    s.sin_addr.s_addr = htonl(IP_ADDR);

    if (connect(sock, (struct sockaddr*)&s, sizeof(s)) < 0)
    {
        perror("connect");
        return 1;
    }

    printf("Successfully connected.\n");
    char buffer[1000] = {0};

    if ((nrecv = recv(sock, &buffer, sizeof(buffer), 0)) < 0)
    {
        perror("recv");
        return 1;
    }

    printf("./client list-files\n%s\n", buffer); //nrcev gives the size of the data is recived

    int fd;
    //int i;
    //ssize_t nwrite, nread;
    char sizebuff[256];
    struct stat file_stat;
    int numcheck = 0;
    //char buffer2[4096];
    char namebuff[100] = "coolfile.txt";
    fd=open("coolfile.txt",O_RDONLY);

    if (send(sock, &namebuff, strlen(namebuff), 0) < 0)
        {
            perror("send");
            return 1;
        }

    /*if ((nrecv = recv(sock, &numcheck, sizeof(int), 0)) < 0)
    {
        perror("recv");
        return 1;
    }*/

    if (numcheck == -1)
    {
        printf("file already exists in the server\n");
        return 1;
    }

        if (fstat(fd, &file_stat) < 0)
            {
            printf("error");

                    return 1;
            }

        sprintf(sizebuff, "%ld", file_stat.st_size);
        //printf("%s\n",sizebuff);
        /*int number = 5;

        if(send(sock, &number, sizeof(int), 0) < 0)
            {
                    printf("error");

                    return 1;
            }*/


        if(send(sock, &sizebuff, strlen(sizebuff), 0) < 0);
            {
                    printf("error");

                    return 1;
            }
        /*
        nread = read(fd, buffer2, 4096);

        for (i = 0; i < nread; i += nwrite)
        {
            nwrite = write(sock, buffer2 + i, nread - i);
        }

    } while (nread != 0);*/
    return 0;
}

Спасибо за вашу помощь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...