如何在C中的套接字编程中同步send和recv调用?

时间:2015-03-10 06:18:12

标签: c sockets send recv

我想将完整的文件夹从客户端发送到服务器。该文件夹有二进制文件。但是现在我正在使用文件夹中的文本文件。由于我一步一步走,我目前正在处理类似于显示文件夹中文件名称的内容:

  1. 打开目录
  2. 阅读整个目录
  3. 从客户端向服务器一个接一个地发送文件名称
  4. 服务器正在接收
  5. 整个文件夹完成从中读取所有文件后,文件夹将关闭。
  6. 我面临的问题是: 在发送文件名时,服务器正确接收文件名,但是当服务器忙于从缓冲区中取出东西时,客户端已经将下一个文件名写入缓冲区,因此两个或多个文件名被附加到缓冲区和服务器一次读取所有内容。

    如何解决此问题,因为我希望客户端一次只发送一个文件名,服务器应该只收到一个文件名。我应该如何同步这些电话?或者我应该如何限制缓冲区?

    Server.c

    #include<stdio.h>
    #include<stdlib.h>
    #include<errno.h>
    #include<string.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include <sys/un.h>
    
    #define MAX 1024
    #define SOCK_PATH "/tmp/foo"
    
    int s, s2, t, len;
    struct sockaddr_un local, remote;
    
    void createSSocket()
    {
        if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 
        {
            perror("socket");
            exit(1);
        }
        printf("\nServer Socket Created...");
    }
    
    void setSSocketPath()
    {
        local.sun_family = AF_UNIX;
        strcpy(local.sun_path, SOCK_PATH);
        unlink(local.sun_path);
        len = strlen(local.sun_path) + sizeof(local.sun_family);
        printf("\nServer Socket Path Set...");
    }
    
    void bindSocket()
    {
        if (bind(s, (struct sockaddr *)&local, len) == -1) 
        {
            perror("bind");
            exit(1);
        }
        printf("\nSocket Binded...");
    }
    
    void listenSocket()
    {   
        if (listen(s, 5) == -1) 
        {
              perror("listen");
              exit(1);
        }
        printf("\nListening Socket...");
    }
    
    void acceptConnection()
    {
        printf("\nWaiting for a connection...");
        t = sizeof(remote);
        if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) 
        {
            perror("accept");
            exit(1);
        }
        printf("\nServer Socket Connected...");
    }
    
    void closeSSocket()
    {
        close(s2);
        printf("\nServer Socket Closed...");
    }
    
    void receiveData()
    {
        char str[MAX] = {0};
        int n;
        while(1)
        {
            //printf("\n%d ... %s",n,str);
            n = recv(s2, str, MAX, 0);
            str[n] = 0;
            printf("\n%d ... %s",n,str);
            if(!strcmp(str,"@#$%")) // 2345
            break;
        }
    }
    
    int main()
    {
        createSSocket();    
        setSSocketPath();
        bindSocket();
        listenSocket();
        acceptConnection();
    
        receiveData();
    
        closeSSocket();
        return 0;   
    }
    

    Client.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <dirent.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/un.h>
    
    #define MAX 1024
    #define SOCK_PATH "/tmp/foo"
    
    
    int s, t, len;
    struct sockaddr_un remote;
    char path[MAX] = "/home/priyanka/criu-1.4/3455";  //to retieve path from folder
    DIR *dirDes;
    struct dirent *expFile;
    
    void createCSocket()
    {
        if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 
        {
            perror("socket");
            exit(1);
        }
        printf("\nClient Socket Created...");
    }
    
    void setCSocketPath()
    {
        remote.sun_family = AF_UNIX;
        strcpy(remote.sun_path, SOCK_PATH);
        len = strlen(remote.sun_path) + sizeof(remote.sun_family);
        printf("\nClient Socket Path Set...");
    }
    
    void connectSocket()
    {
        printf("\nTrying to connect...");
        if (connect(s, (struct sockaddr *)&remote, len) == -1) 
        {
            perror("connect");
            exit(1);
        }
        printf("\nClient Connected...\n");
    }
    
    void closeCSocket()
    {
        close(s);
        printf("\nClient Socket Closed...");
    }
    
    void readDirectory()
    {
        char temp[MAX] = {0};
        dirDes = opendir(path);     //open the directory in which files related to process are dumped
        if(dirDes == NULL)
            printf("Error Opening Directory !!! \n");
       else
       {
            while(expFile = readdir(dirDes))    //read the directory
            {
                int bb;
                char str[MAX] = {0};
                if(strcmp(expFile -> d_name,".") == 0)      //skip folder with name "."
                    continue;
                if(strcmp(expFile -> d_name,"..") == 0)     //skip folder with name ".."
                    continue;
                strcpy(temp,path);
                if(temp[strlen(temp)-1]!='/')       //if the temp has / appended at the end skip else append
                strcat(temp,"/");
                strcat(temp,expFile->d_name);       //append the file name read to the path
                printf("\n%s",temp);
                sprintf(str,"%d",strlen(temp));
                bb = send(s,str,strlen(str),0);
                if(bb == -1)
                {
                    perror("Error sending file name length");
                }
                bb = send(s,temp,strlen(temp),0);
                //sleep(1);
                if(bb == -1)
                {
                    perror("Error sending file name");
                }
                /*else
                {
                    printf("Name sent 1\n");
                }*/
            }   
            closedir(dirDes);       //close directory
            send(s,"@#$%",strlen("@#$%"),0);
        }
    }
    
    
    int main()
    {
        createCSocket();
        setCSocketPath();
        connectSocket();
    
        readDirectory();    
    
        closeCSocket(); 
        return 0;
    }
    

0 个答案:

没有答案