如何获取刚刚从套接字接收到的缓冲区的长度?
How to get length of the buffer which is just received from socket?
我正在使用与服务器的 #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������ t�� ��{�� ���� ������ ���� ������ ��Ʈ ή��ծ ���� ������ ����
那么我们有什么方法可以获得准确的响应大小吗?
根据 @Dai。我应该使用函数 read
的 return 值
再次感谢。
始终检查 C 风格 API 中的 return 值!
C 风格的 API 可以直接从大多数其他编程语言(包括 C++)调用。因为可移植 C 不支持抛出的异常 C 风格库 API 被设计为通常通过 return 值(例如 returning NULL
或负值)指示错误条件,而 输出数据(例如字节缓冲区、结构指针等)通过作为参数传递的指针传递。因为 C 公开了原始程序内存,这意味着如果您尝试使用无效指针或者如果您使用的库指示它处于无效状态或终止状态(例如 eof
在文件流上)。
POSIX的read
函数returns实际写入缓冲区的字节数。
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.
注意这部分:
this may happen for example because fewer bytes are actually available right now
...这意味着您需要在循环中调用 read
直到它 return 为零。
像这样:
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;
}
}
我正在使用与服务器的 #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������ t�� ��{�� ���� ������ ���� ������ ��Ʈ ή��ծ ���� ������ ����
那么我们有什么方法可以获得准确的响应大小吗?
根据 @Dai。我应该使用函数 read
的 return 值
再次感谢。
始终检查 C 风格 API 中的 return 值!
C 风格的 API 可以直接从大多数其他编程语言(包括 C++)调用。因为可移植 C 不支持抛出的异常 C 风格库 API 被设计为通常通过 return 值(例如 returning NULL
或负值)指示错误条件,而 输出数据(例如字节缓冲区、结构指针等)通过作为参数传递的指针传递。因为 C 公开了原始程序内存,这意味着如果您尝试使用无效指针或者如果您使用的库指示它处于无效状态或终止状态(例如 eof
在文件流上)。
POSIX的read
函数returns实际写入缓冲区的字节数。
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.
注意这部分:
this may happen for example because fewer bytes are actually available right now
...这意味着您需要在循环中调用 read
直到它 return 为零。
像这样:
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;
}
}