【问题标题】:Sending messages to java server in objective-c via AsyncSocket通过AsyncSocket在objective-c中向java服务器发送消息
【发布时间】:2013-08-01 07:44:03
【问题描述】:

您好,我正在尝试向 Java 服务器发送无法从 iOS 设备更改的消息。我正在使用 AsyncSocket 并且想知道如何发送和接收附加到字符串的长度。我正在将字符串 UTF 转换为 NSData 但是我想知道这两种语言之间的原语大小是否存在差异。还有大端和小端的变化吗?基本上我需要能够转换以下java方法:

inStream.readUTF();
inStream.readInt();
inStream.readChar();
inStream.readShort();
inStream.readFully(recvBuff, 0, recvLen);

outStream.writeInt();
outStream.writeUTF();
outStream.writeChars();
outStream.writeShort();
outStream.write(sendBytes, 0, sendBytes.length);

我知道我很接近,但有些地方不太对劲,这就是我目前所得到的:

我正在使用 NSMutableArray 来附加数据并使用 AsyncSockets 读取和写入方法。

[theSocket readDataToData:[AsyncSocket ZeroData] withTimeout:timeout buffer:buffer bufferOffset:offset tag:tag]; // inStream.readUTF();
[theSocket readDataToLength:sizeof(int32_t) withTimeout:timeout buffer:buffer bufferOffset:offset tag:tag]; // inStream.readInt();
[theSocket readDataToLength:sizeof(unichar) withTimeout:timeout buffer:buffer bufferOffset:offset tag:tag]; // inStream.readChar();
[theSocket readDataToLength:sizeof(int16_t) withTimeout:timeout tag:tag]; // inStream.readShort();
[theSocket readDataWithTimeout:timeout buffer:buffer bufferOffset:offset maxLength:maxLength tag:tag]; // inStream.readFully(recvBuff, 0, recvLen);

[outputBufferStream appendBytes:&[sendString length] length:sizeof([sendString length])]; // outStream.writeInt();
[outputBufferStream appendData:[sendString dataUsingEncoding:NSUTF8StringEncoding]] // outStream.writeUTF();
char array[5];
[outputBufferStream appendBytes:array length:sizeof(array)]; // outStream.writeChars();
int16_t _short;
[outputBufferStream appendBytes:&_short length:sizeof(_short)]; // outStream.writeShort();
unsigned char *sendBytes;
[outputBufferStream appendBytes:sendBytes length:sendBytesLength]; // outStream.write(sendBytes, 0, sendBytes.length);

我通常像这样在开头附加长度:

int32_t sendStringLength = [sendString length];
[outputBufferStream appendBytes:&sendStringLength length:sizeof(sendStringLength)];

在写结束时,我将以下内容作为终止符附加:

[outputBufferStream appendData:[@"\n" dataUsingEncoding:NSUTF8StringEncoding]];

我非常感谢任何帮助。谢谢。

编辑::

多亏了 Robadob,我已经完成了大部分工作。这是我目前试图在 Objective-C 上工作的一点 java sn-p(工作):

private int sendData(String stringToSend) {
    if (theSocket==null) {
        lastError="sendData() called before socket was set up.";
        return 1; // Error
    }

    try {
        System.out.println("Sending "+stringToSend.length()+" chars  ["+ stringToSend.length()*2+" bytes]");
        System.out.println("'" + stringToSend + "'");
        outStream.writeInt(stringToSend.length()*2);
        outStream.writeChars(stringToSend);
        outStream.flush();

    } catch (IOException e) {
        lastError="sendData() exception: "+e;
        System.out.println(lastError);
        return 2; // Error
    }

    return 0; // Ok
}

这是我目前在 Objective-C 中得到的一个 sn-p:

- (int32_t)sendData:(NSString *)stringToSend {

    if (theSocket == nil) {
        lastError = @"sendData called before socket was set up";
        return 1; // Error
    }

    @try {

        NSLog(@"Sending %d chars  [%d bytes]", [stringToSend length], ([stringToSend length] * 2));
        NSLog(@"'%@'", stringToSend);

        uint32_t stringToSendInt = ([stringToSend length] * 2);
        uint32_t stringToSendIntBigE = CFSwapInt32HostToBig(stringToSendInt);
        [outputBufferStream appendBytes:&stringToSendIntBigE length:sizeof(stringToSendIntBigE)];
        stringToSend = [stringToSend stringByAppendingString:@"\n"];
        for (int i = 0; i < ([stringToSend length]); i++) {
            unichar characterTmp = [stringToSend characterAtIndex:i];
            unichar character = characterTmp << 8;
            [outputBufferStream appendBytes:&character length:sizeof(character)];
        }

        [self syncWriteData:outputBufferStream withTimeout:socketTimeout tag:kSendDataSocketTag];
        outputBufferStream = [NSMutableData data];

    }
    @catch (NSException *e) {
        lastError = [NSString stringWithFormat:@"sendData exception: %@", [e reason]];
        NSLog(@"%@", lastError);

        return 2; // Error
    }

    return 0; // Ok
}

【问题讨论】:

    标签: java objective-c sockets stream primitive


    【解决方案1】:

    如果您阅读 writeUTF 的文档,它会说它使用 writeShort 写入前 2 个字节。这是说

    以两个字节,高字节写入底层输出流 第一的。如果没有抛出异常,则写入的计数器递增 2.

    一个字节是 8 位,因此它们写入的值是 16 位,您使用的是 32 位 int32_t。你应该写一个int16int16_t(我不客观-c)。

    【讨论】:

    • 非常感谢您的快速回复,我会更正此问题并查看它是否有效:) 如果您有兴趣,它是 int16_t。
    • 是的,我检查了它们都是 32 位,我使用 int32_t 只是为了安全,但我不确定大端/小端转换。再次感谢您的帮助。
    • 我设法让它部分工作我似乎仍然无法弄清楚如何转换 writeChars() 方法
    • 所以您收到的长度正确吗?如果您阅读writeChars(String) 的文档,它只会按顺序为字符串中的每个字符调用writeChar()
    • 不是我没有得到关于长度的回应。问题是当使用 write char 时 java 如何处理它?字符的编码是什么?我一直在查看 writeChar() 的 java 文档并尝试了不同的方法,但还没有弄清楚。
    猜你喜欢
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 2010-09-14
    • 2011-11-23
    • 2023-04-03
    • 1970-01-01
    • 2011-01-12
    相关资源
    最近更新 更多