C socket: recv and send all data

后端 未结 3 1826
悲&欢浪女
悲&欢浪女 2020-12-14 12:11

I would like to obtain a behavior similar to this:

  1. Server run
  2. Client run
  3. Client type a command like \"help\" or other
  4. Server respond
相关标签:
3条回答
  • 2020-12-14 12:18

    I choose to send before each send() if i have to continue or not.

    so i first have 3 define

    #define BUFFSIZE 1024
    #define CONT "CONT"
    #define DONE "DONE"
    

    Then to send my data

    int     send_to_socket(int sock, char *msg)
    {
        size_t  len;
        int     ret[2];
    
        len = strlen(msg);
        ret[0] = send(sock, (len <= BUFFSIZE) ? DONE : CONT, 4, 0);
        ret[1] = send(sock, msg, BUFFSIZE, 0);
        if (ret[0] <= 0 || ret[1] <= 0)
        {
            perror("send_to_socket");
            return (-1);
        }
        if (len > BUFFSIZE)
            return (send_to_socket(sock, msg + BUFFSIZE));
        return (1);
    }
    

    And to receive it :

    char    *recv_from_socket(int cs)
    {
        char    state[5];
        char    buff[BUFFSIZE+1];
        char    *msg;
        int     ret[2];
    
        msg = NULL;
        while (42)
        {
            bzero(state, 5);
            bzero(buff, BUFFSIZE+1);
            ret[0] = recv(cs, state, 4, 0);
            ret[1] = recv(cs, buff, BUFFSIZE, 0);
            if (ret[0] <= 0 || ret[1] <= 0)
            {
                perror("recv_from_socket");
                return (NULL);
            }
            // strfljoin() is selfmade
            // join the string and free the left argument to prevent memory leaks.
            // return fresh new string
            msg = (msg) ? ft_strfljoin(msg, buff) : strdup(buff);
            if (strncmp(state, DONE, 4) == 0)
                break ;
            i++;
        }
        return (msg);
    }
    
    0 讨论(0)
  • 2020-12-14 12:24

    The recv() and send() functions do not guarantee to send/recv all data (see man recv, man send)

    You need to implement your own send_all() and recv_all(), something like

    bool send_all(int socket, void *buffer, size_t length)
    {
        char *ptr = (char*) buffer;
        while (length > 0)
        {
            int i = send(socket, ptr, length);
            if (i < 1) return false;
            ptr += i;
            length -= i;
        }
        return true;
    }
    

    The following guide may help you Beej's Guide to Network Programming

    0 讨论(0)
  • 2020-12-14 12:28

    Usual problems.

    void excCommand(char *command)
    {
        if ( send(sock, command, strlen(command), 0) < 0)
            ErrorWithSystemMessage("send() failed");
    
        char replyMessage[BUFSIZE];
        ssize_t numBytesRecv = 0;
        do
        {
            numBytesRecv = recv(sock, replyMessage, BUFSIZE, 0);
            if ( numBytesRecv < 0)
                ErrorWithSystemMessage("recv() failed");
            printf("%s\n", replyMessage);
    

    Invalid. numBytesRecv could have been zero, in which case there is no message at all, otherwise at this point must be positive, as you've already tested for negative, and it indicates the actual length of the message, which isn't necessarily null-terminated. Change to:

        if (numBytesRecv == 0)
            break;
        printf("%.*s\n", numBytesRecv, replyMessage);
    

    and then:

            memset(&replyMessage, 0, sizeof(replyMessage));
    

    Pointless. Remove.

        }
        while (numBytesRecv > 0);
    

    At this point you should check for numBytesRecv < 0 and call perror() or one of its friends.

    0 讨论(0)
提交回复
热议问题