C socket: recv and send all data

C socket: recv and send all data

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 Beejs Guide to Network Programming

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(%sn, replyMessage);

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

    if (numBytesRecv == 0)
        break;
    printf(%.*sn, 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.

C socket: recv and send all data

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

Leave a Reply

Your email address will not be published.