如何获取刚刚从套接字接收的缓冲区的长度?



>我正在使用与服务器的#include <sys/socket.h>库套接字连接,并使用char类型的vector从套接字连接接收数据,如下所示:

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

由于服务器响应大小的长度是可变的,但不超过1024所以为什么buffer的大小固定为1024。 现在,由于我收到可变大小的响应,我想知道buffer的大小。 我尝试了以下操作:

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

输出为

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

如果我尝试1024值,则会出现一些垃圾值,如下所示:

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

输出:

[{"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 { Ʈ ή ծ

那么有什么方法可以得到确切的响应大小呢?

始终检查 C 样式 API 中的返回值!

C 样式的 API 可以直接从大多数其他编程语言(包括C++)调用。由于可移植 C 不支持抛出的异常 C 样式库 API 通常通过返回值(例如返回NULL或负值)来指示错误条件,而输出数据(例如字节缓冲区、结构指针等)则通过作为参数传递的指针传递。因为 C 公开了原始程序内存,这意味着如果你尝试使用无效的指针,或者如果你使用的库指示它处于无效状态或终端状态(例如eof在文件流上)。


POSIX 的read函数返回实际写入缓冲区的字节数。

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

成功时,返回读取的字节数(零表示 文件末尾),并且文件位置按此数字前进。

如果此数字小于 请求的字节数;例如,这可能是因为字节较少 实际上现在可用(也许是因为我们接近 文件末尾,或者因为我们从管道或从 终端),或因为read()被信号打断。

请注意此部分:

例如,这可能会发生,因为现在实际可用的字节较少

。这意味着您需要在循环中调用read,直到它返回零。

这样:


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

根据@Dai。我应该使用函数的返回值read再次感谢。

最新更新