Umang Patel
Umang Patel

Reputation: 19

How to get length of the buffer which is just received from socket?

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?

Upvotes: 0

Views: 1354

Answers (2)

Dai
Dai

Reputation: 155145

Always inspect return-values in C-style APIs!

C-style APIs are directly callable from most other programming languages, including C++. Because portable C doesn't support thrown exceptions C-style library APIs are designed indicate error conditions typically through return-values (e.g. returning NULL or a negative value) while output data (e.g. byte buffers, struct pointers, etc) is passed through pointers passed as parameters. Because C exposes raw program memory it means that you can easily crash your process (or worse...) if you attempt to use an invalid pointer or if the library you're using indicates it's in an invalid-state or terminal-state (e.g. eof on file streams).


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

Upvotes: 1

Umang Patel
Umang Patel

Reputation: 19

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

Upvotes: 0

Related Questions