使用来自NSInputStream的转换字节的麻烦?

时间:2015-03-01 00:12:09

标签: ssl encoding openssl buffer inputstream

我有openssl服务器和Objective-C客户端。我发送这样的信息

uint32_t testD = 161;
err = SSL_write(ssl_, &testD, sizeof(uint32_t));

并通过NSInputStream读取,如

case NSStreamEventHasBytesAvailable:
        {
                uint8_t buffer[4];
                int len;
                while ([inStream hasBytesAvailable])
                {
                    len = [inStream read:buffer maxLength:sizeof(buffer)];
                    if (len > 0)
                    {
                        NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
                        NSData *theData = [[NSData alloc] initWithBytes:buffer length:len];
                        if (nil != output)
                        {
                            char buff;
                            [theData getBytes:&buff length:1];
                            uint32_t temp = (uint32_t)buffer;
                        }
        ...

所以,在输出中我有“¡”,它是第161个ASCII符号,在buff中我有'\ xa1'并且在temp非常大的数字,但实际上我需要161在temp。

我读到'\ xa1'它也是161,但是我无法将其转换为uint32_t。 有什么问题?


解答:

问题在于铸造。这对我来说很好:

unsigned char buff;
int temp = buff;

char buff;
int b = (unsigned char) buff;

3 个答案:

答案 0 :(得分:2)

SSL_write(),不使用编码,\xa1 == 161是数学标识,而不是任何编码过程的结果。当您成功恢复\xa1,时,NSInputStream也不会使用解码。

在我看来,你正在转换缓冲区的地址而不是其内容,这就是为什么你得到一个随编译而变化的高值。

此外,您可能通过阅读可用的内容来过度运行数据,然后只消耗四个字节:事实上,因为您错误地测试了len >= 1而不是len >= 4.

你应该:

  1. 使用恰好四个字节的缓冲区。无需动态分配它:您可以将其声明为本地数组。
  2. 读取,直到读完四个字节。这需要循环。
  3. 更改播放语法(不要问我怎么样,我没有Objective-C专家,但恢复buff的代码看起来是一个好的开始),所以你得到了缓冲区的内容而不是地址。
  4. 之后,您可能会遇到字节序问题。

    与编码无关。

答案 1 :(得分:0)

我们可以得到像这样的单字节值:

unsigned char buff;
int temp = buff;

或者

char buff;
int b = (unsigned char) buff;

答案 2 :(得分:0)

  

SSL_write和NSInputStream中使用了什么编码?

没有编码。它的字节输入和字节输出。

认为您正在寻找network byte order/endianess

网络字节顺序是大端。所以你的代码将成为:

uint32_t testD = 161;
uint32_t be = htonl(testD);
err = SSL_write(ssl_, &be, sizeof(be));

以下是htonl手册页中htonl(3)的说明:

  

htonl()函数将无符号整数hostlong从主机字节顺序转换为网络字节顺序。

要转换回来,您可以使用ntohl

我不确定Cocoa / CocoaTouch是否替代htonlntohl。所以你可能也必须在你的iPhone项目中使用它们。例如,请参阅Using ntohl and htonl problems on iPhone