字符数组中的十六进制在写入套接字时产生随机字符
问题描述:
当与外部系统通信时,他们希望我在响应结束时添加空字节。不过我现在面临的一些问题:字符数组中的十六进制在写入套接字时产生随机字符
//reading from socket
//sending response
std::string response = "hardcodedResponse";
int bufferSize = response.size() + 1; // +1 for the trailing zero
char buffer[bufferSize];
for (int i = 0; i < response.size(); i++)
{
buffer[i] = response[i];
}
buffer[bufferSize] = 0x00;
int socketfd = 1;
unsigned bytesWritten = 0;
while (bytesWritten < bufferSize)
{
bytesWritten += ::write(socketfd, buffer[bytesWritten], bytesToWrite - bytesWritten);
}
当我使用telnet来送东西到插座,我得到答复:“hardcodedResponse”后跟一个▒。我认为这是有道理的,因为0x00为空。但是,如果我将0x41(A)添加到最后,我会收到“hardcodedResponse”+一个(看似)随机字符。如果我在写入套接字之前打印缓冲区的最后一个字符,它会打印'A'。如果外部系统也接收到正确的字节,这并不重要,但是,它们会收到随机的字节。
我不知道为什么会发生这种情况。希望有人能帮助我理解。
答
除了所有的插座,看看缓冲区长度,你把空:
std::string response = "hardcodedResponse";
int bufferSize = response.size() + 1; // +1 for the trailing zero
char buffer[bufferSize]; //Up to, but not including bufferSize
//0, 1, ... bufferSize-1
for (int i = 0; i < response.size(); i++)
{
buffer[i] = response[i];
}
buffer[bufferSize] = 0x00; //BOOM udefined behaviour
您为空,而不是两个做一个额外的字符,这样就把空在最后无法超越结束。
buffer[bufferSize-1] = 0x00;
答
首先,您正在依赖称为“可变长度阵列”的非标准功能。只有少数C++编译器支持VLA,然后才作为可选的扩展。您应该使用STL std::vector
容器代替动态大小的数组。
但是,更重要的是,您正在将空字节写入错误的数组索引。 buffer[]
的有效索引范围是0..bufferSize-1
。写入buffer[bufferSize]
将不会在数据末尾的正确位置追加空终止符,并且它会清除周围的内存。
您需要更改此:
buffer[bufferSize] = 0x00;
要这样:
buffer[bufferSize-1] = 0x00;
您还没有正确管理调用write()
,无论是。特别是,它可以返回-1错误,你不处理。你应该使用bufferSize
而不是bytesToWrite
。
话虽这么说,你实际上并不需要buffer[]
阵列可言,你可以发送std::string
数据,反而:
//sending response
std::string response = "hardcodedResponse";
const char *buffer = response.c_str();
const size_t bufferSize = response.size() + 1; // +1 for the trailing zero
size_t totalWritten = 0;
ssize_t bytesWritten;
do
{
bytesWritten = ::write(socketfd, buffer[totalWritten], bufferSize - totalWritten);
if (bytesWritten <= 0)
{
// handle error...
break;
}
totalWritten += bytesWritten;
}
while (totalWritten < bufferSize);
或者:
//sending response
std::string response = "hardcodedResponse";
const char *buffer = response.c_str();
size_t bufferSize = response.size() + 1; // +1 for the trailing zero
size_t totalWritten = 0;
ssize_t bytesWritten;
do
{
bytesWritten = ::write(socketfd, buffer, bufferSize);
if (bytesWritten <= 0)
{
// handle error...
break;
}
buffer += bytesWritten;
bufferSize -= bytesWritten;
}
while (bufferSize > 0);
妈的,我是如此专注于六角形/插座部分,我完全没有看到这一点。谢谢 :) – Aelion