-2

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".

lcocozza
  • 5
  • 3
  • To start, if your first `recv()` reads a full 6 chars, `buffer` is no longer a 0 terminated string and passing it to `atoi()` is thus an issue... – Shawn Mar 25 '19 at 18:23
  • what is `ft_itoa`? where does it write the string ... or does it return it? If it returns it, who is responsible for freeing it? why not `snprintf` ? – MFisherKDX Mar 25 '19 at 18:26
  • the first send() send the size of buffer and the second send() send the buffer the first recv() receive the size of buffer who will be sending to realloc the buffer in recv_net(), so it's why i don't alloc more than 6, in theory i juste need 4 because i never send/receive more than 999 char. ft_itoa convert int to str, i have write it, why i don't use snprintf ? i don't know – lcocozza Mar 25 '19 at 18:45
  • `itoa()` and `atoi()` aren't portable, you shouldn't be using them. – S.S. Anne Mar 26 '19 at 15:26

1 Answers1

2

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
001
  • 13,291
  • 5
  • 35
  • 66