C套接字:如果两次使用recv会阻塞程序

时间:2018-12-01 21:18:49

标签: c sockets unix

我正在尝试在UNIX平台上使用c代码,该代码将所有文件数据发送到客户端,并将文件从客户端上传到服务器。

第一部分正在工作,但是第二部分我遇到了一个问题。 经过一些调试后,我发现我在代码中第二次使用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;
}

感谢您的帮助!

0 个答案:

没有答案