char数组中的十六进制导致写入套接字时出现随机字符
Posted
技术标签:
【中文标题】char数组中的十六进制导致写入套接字时出现随机字符【英文标题】:Hex in char array resulting in random character when writing to socket 【发布时间】:2018-01-12 10:00:20 【问题描述】:在与外部系统通信时,他们希望我在响应的末尾添加一个空字节。但是我面临一些问题:
//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”。如果外部系统也接收到正确的字节,这并不重要,但可惜的是,它们接收的是随机的。
我不知道为什么会这样。希望有人能帮助我理解。
【问题讨论】:
【参考方案1】:除了所有的套接字,看看缓冲区长度和你放置空值的位置:
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
你为 null 增加了一个字符,而不是两个,所以将 null 放在末尾而不是末尾。
buffer[bufferSize-1] = 0x00;
【讨论】:
该死,我太专注于六角/插座部分,我完全没有看到。谢谢:)【参考方案2】:首先,您依赖于称为“可变长度数组”的非标准功能。只有少数 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);
【讨论】:
以上是关于char数组中的十六进制导致写入套接字时出现随机字符的主要内容,如果未能解决你的问题,请参考以下文章
使用 C++ 将半字写入闪存时出现 ARM Cortex-M HardFault 异常