Search code examples
csocketssendrecv

C socket, recv lose data


I made a TCP client/server, and i want send request, but recv function lose data (3rd first bytes of buffer sended)

I have tried a lots of things:

-put printf everywhere

-change port number

-change/optimized my code

-use wireshark

-use flags MSG_WAITALL and MSG_PEEK in loop while size of bytes receive is different than size of buffer previously sending (and I have seen the buffer stocked in the socket is cut, so i lose bytes between send() and recv() ?)

-maybe other things but i don't remember.

int send_net(SOCKET socket, const char *buffer)
{
    if (send(socket, ft_itoa(strlen(buffer) + 1), strlen(ft_itoa(strlen(buffer))) + 1, 0) == -1)
    {
        perror("send size");
        return -1;
    }
    if (send(socket, buffer, strlen(buffer) + 1, 0) == -1)
    {
        perror("send buffer");
        return -1;
    }
    return 0;
}
char    *recv_net(SOCKET socket)
{
    unsigned int size;
    char *buffer = NULL;
    int bytes;

    buffer = calloc(6, sizeof(char));

    if ((bytes = recv(socket, buffer, 6, MSG_WAITALL)) == -1)
    {
        perror("recv size");
        return NULL;
    }

    size = atoi(buffer);
    buffer = realloc(buffer, sizeof(char) * size);
    bzero(buffer, size);

    if ((bytes = recv(socket, buffer, sizeof(char) * size, MSG_WAITALL)) != -1)
    {
        perror("recv buffer");
        return NULL;
       }
    return buffer;
}

I want to send "GET Host List" and i receive " Host List".


Solution

  • Looks like you are sending 14\0GET Host List\0. The main issue is you read 6 bytes for the message size no matter how many bytes are sent. Since you are sending the \0 you can use that to know when to stop reading:

    buffer = calloc(6, sizeof(char));
    int index = 0;
    char c;
    
    do {
        // Read a single byte
        bytes = recv(socket, &c, 1, MSG_WAITALL);
        // Check for error
        if (-1 == bytes) {
            perror("recv size");
            return NULL;
        }
        // Append to buffer
        buffer[index++] = c;
        // TODO: realloc if more than 5 digits    
    } while (c != 0);
    
    // Now buffer should contain a null-terminated string of digits