Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在不断开客户端连接的情况下通过套接字连接获取google协议缓冲区消息?_Java_Iphone_Objective C_Sockets_Protocol Buffers - Fatal编程技术网

Java 如何在不断开客户端连接的情况下通过套接字连接获取google协议缓冲区消息?

Java 如何在不断开客户端连接的情况下通过套接字连接获取google协议缓冲区消息?,java,iphone,objective-c,sockets,protocol-buffers,Java,Iphone,Objective C,Sockets,Protocol Buffers,我正试图通过套接字连接将.proto消息从iPhone应用程序发送到Java服务器。然而,到目前为止,当服务器接收数据时,我遇到了一个问题;它似乎只在客户端连接终止后处理它。这向我指出,数据正在被发送,但服务器保持其inputstream打开并等待更多数据。有人知道我该怎么解决这个问题吗?当前代码(或至少相关部分)如下所示: iPhone: Person *person = [[[[Person builder] setId:1] setName:@"Bob"] build]; RequestW

我正试图通过套接字连接将.proto消息从iPhone应用程序发送到Java服务器。然而,到目前为止,当服务器接收数据时,我遇到了一个问题;它似乎只在客户端连接终止后处理它。这向我指出,数据正在被发送,但服务器保持其inputstream打开并等待更多数据。有人知道我该怎么解决这个问题吗?当前代码(或至少相关部分)如下所示:

iPhone:

Person *person = [[[[Person builder] setId:1] setName:@"Bob"] build];
RequestWrapper *request = [[[RequestWrapper builder] setPerson:person] build];
NSData *data = [request data];  
AsyncSocket *socket = [[AsyncSocket alloc] initWithDelegate:self];

if (![socket connectToHost:@"192.168.0.6" onPort:6666 error:nil]){
    [self updateLabel:@"Problem connecting to socket!"];
} else {
    [self updateLabel:@"Sending data to server..."];
    [socket writeData:data withTimeout:-1 tag:0];
    [self updateLabel:@"Data sent, disconnecting"];
    //[socket disconnect];
}
爪哇:

运行此命令时,它似乎挂在RequestWrapper处理inputStream的行上。我确实尝试将套接字writedata方法替换为:

[request writeToOutputStream:[socket getCFWriteStream]];
(这里我调用gpb写入输出流,而不是将生成的数据写入输出流)

我认为这可能有效,但是我得到一个错误,声称“协议消息包含无效标记(零)”。我很确定它没有包含无效的标记,因为通过writedata方法发送消息时消息是有效的

在此问题上的任何帮助都将不胜感激

干杯


(编辑:我应该提到,我使用的是元语法gpb代码;以及cocoaasyncsocket实现)

可能需要刷新iPhone端的输出套接字,可能数据位于OS/库缓冲区中,在连接关闭之前不会被写入(这会导致隐式刷新)

编辑

看起来api不支持刷新(我想刷新不是一件非常异步的事情),但是您可以从标题订阅
didWriteDataWithTag
事件

/**
 * Called when a socket has completed writing the requested data. Not called if there is an error.
**/
- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
我将订阅此事件,然后在事件处理程序调用中

[self updateLabel:@"Data sent, disconnecting"];
[socket disconnect];
这样,只有在实际发送数据时才显示“已发送数据”标签


(为了充分披露,我不知道如何在objective-c中编程:)祝你好运)

最后我设法解决了它!!当我不再关心GPB的方式时,它是多么的简单,真让人尴尬。我使用的C++代码是:

    NSData *data = [wrapper data]; 
    int s = [wrapper serializedSize]; 
    NSData *size = [NSData dataWithBytes:&s length:1]; 
    [sock writeData:size withTimeout:-1 tag:1]; 
    [sock writeData:data withTimeout:-1 tag:1]; 
然后在Java端,我只保留了

    RequestWrapper.parseDelimitedFrom(socket.getInputStream())
这是一种享受!我最后要做的就是在数据本身和Java端的GPB方法解决其余问题之前发送数据的大小

我遇到的一个主要问题实际上是将要发送的数据的大小从int转换为NSData,并通过网络正确发送。有人建议我做这件事的方式是 NSData*size=[NSData dataWithBytes:&s长度:sizeof(s)]

然而,每当我将其作为数据发送时,它似乎会发送第一个字节,以及3个“0”字节。这对GPB造成了极大的破坏,因为如果它在任何一点接收到0字节,它就会抛出一个异常,认为代码已经损坏(我猜)。看到我从来没有看过遇到的实际字节并对它们进行分析,直到今天我尝试用另一种方式进行分析,我有点泄气,因为我早就知道这是问题所在。在对它进行了一些实验之后,我发现“sizeof”方法是问题所在,所以我将其删除。目前,我只放了一个“1”而不是实际大小,这 通过网络发送数据文件时,似乎只返回1字节;尽管我不确定这是否是一个“理想”的解决方案(尽管消息大小无论如何只能为1字节)-如果有人能告诉我为什么这个sizeof()会引起问题,我们将不胜感激:)


尽管我很愚蠢,但Luke Steffen还是帮了我在CocoaSocket谷歌群上的这一点。所以再次感谢Luke

我已经考虑过了,但是似乎没有一种方法可以通过cocoaasyncsocket类来执行刷新…也许我必须把CFStream拉出来才能做到这一点谢谢你的充分披露和运气:p我会一直努力,直到找到一种方法!经进一步检查,“包含无效标记(零)的协议消息”是一种误导;这与试图在java代码中实现CodedInputStream有关。将其更改回正常状态后,我从[request writeToOutputStream:[socket getCFWriteStream]]获得的响应与仅发送数据时相同。
    RequestWrapper.parseDelimitedFrom(socket.getInputStream())