Home > Software design >  How to get length of the buffer which is just received from socket?
How to get length of the buffer which is just received from socket?

Time:12-11

I am using the #include <sys/socket.h> library socket connection with server and using vector of type char for receiving the data from the socket connection which as shown below:

    struct sockaddr_in serv_addr;
    int sock, valread;
    sock = 0;

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("\n Socket creation error \n");
    }

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);

    // Convert IPv4 and IPv6 addresses from text to binary form
    if (inet_pton(AF_INET, "0.0.0.0", &serv_addr.sin_addr) <= 0)
    {
        printf("\nInvalid address/ Address not supported \n");
    }

    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
        printf("\nConnection Failed \n");
    }
    std::vector<char> buffer = {0};
    buffer.reserve(1024);
    read(sock, buffer.data(), 1024);

Since the server response size is variable in length but not more than 1024 so that why the size of buffer fixed to 1024. Now since I am receiving variable size response I want to know the size of the buffer. I tried following:

std::cout<<sizeof(buffer)<<" "<<buffer.size();

and output is

 sizeof(buffer) = 32
 buffer.size() = 1

if I try 1024 value that comes up with the some garbage values which is as follow:

for (int i = 0; i < 1024; i  )
{
    std::cout<<buffer[i];
}

output:

[{"xmin": 95, "ymin": 147, "ymax": 276, "xmax": 193}, {"xmin": 42, "ymin": 353, "ymax": 488, "xmax": 123}, {"xmin": 85, "ymin": 19, "ymax": 166, "xmax": 145}, {"xmin": 1, "ymin": 254, "ymax": 327, "xmax": 107}, {"xmin": 393, "ymin": 281, "ymax": 419, "xmax": 463}, {"xmin": 379, "ymin": 316, "ymax": 457, "xmax": 442}]������� ��!� )��0� 8��?� G��N� V��]� e��l� t��{� ����� ����� ����� ����� ���Ʈ ή�ծ ݮ��� ����� ����

So is there any way we can get exact size of response?

CodePudding user response:

As per the @Dai. I should use the return value of the function read Thanks again.

CodePudding user response:

Always inspect return-values in C programs!

POSIX's read function returns the number of bytes actually written into the buffer.

https://man7.org/linux/man-pages/man2/read.2.html

On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number.

It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal.

Note this part:

this may happen for example because fewer bytes are actually available right now

...which means you need to call read in a loop until it returns zero.

Like so:


using std::vector<char>; // Consider using `std::Array` instead as it's a fixed-size buffer.

//

const size_t bufferLength = 1024;

vector<char> buffer(/*n:*/ bufferLength);

char* bufferPtr = buffer.data();
size_t totalRead = 0;
while( totalRead < bufferLength )
{
    char* bufferPtrOffset = bufferPtr   totalRead;

    ssize_t bytesRead = read( /*fd:*/ sock, /*buffer:*/ bufferPtrOffset, /*count:*/ bufferLength - totalRead );
    if( bytesRead < 0 )
    {
        // TODO: Error condition. Throw an exception or something.
    }
    else if( bytesRead == 0 )
    {
        break;
    }
    else
    {
        totalRead  = bytesRead;
    }
}
  • Related