Hex in char array resulting in random character when writing to socket

时间:2017-08-04 12:45:41

标签: c++ sockets char hex telnet

When communicating with an external system they want me to add a null byte to the end of my response. However I'm facing some problems:

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

When I use telnet to send something to the socket, I do receive a response: "hardcodedResponse" followed by a ▒. I figured that made sense since 0x00 is null. However if I add 0x41 (A) to the end, I receive "hardcodedResponse" + a (seemingly) random character. If I print the last character of the buffer before writing to the socket, it does print 'A'. This wouldn't really matter if the external system would also receive the correct byte, but alas, they receive the random one.

I'm at a loss as to why this is happening. Hopefully someone can help me understand.

2 个答案:

答案 0 :(得分:1)

Aside from all the socket, look at the buffer length and where you put the null:

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

You made one extra char for the null, not two, so put the null at the end not beyond the end.

buffer[bufferSize-1] = 0x00;

答案 1 :(得分:1)

首先,您依赖于称为“可变长度数组”的非标准功能。只有少数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);