我将数据发送到服务器两次。首先,我发送“Hello world”,然后发送“Server”。 但服务器在1读取时收到数据。但是服务器必须以双读操作读取数据。
另外,我写了数据。然后从服务器读取数据,然后我写入数据。 在这种情况下,服务器可以读取第一个数据。但服务器无法读取第二个数据。 服务器使用读,写,读。
那么如何克服这个问题呢?如何在BlackBerry中将数据写入套接字?
答案 0 :(得分:2)
您所描述的是默认情况下TCP应该如何工作。您所看到的是Nagle算法(RFC 896)正在工作,减少了发送的出站数据包的数量,以便尽可能高效地处理它们。您可能在代码中发送了2个数据包,但它们作为1个数据包一起传输。由于TCP是字节流,因此接收方不应对其获得的数据包进行任何假设。您必须在更高级别的协议中划分数据包数据,接收方必须根据该协议处理数据。它必须处理多个数据包在一次读取中到达的情况,一个pakcet到达多个读取,以及介于两者之间的所有内容,仅在完全接收到数据包时处理数据包数据,缓存剩余的内容以供后续读取处理需要的。
答案 1 :(得分:1)
很难说没有更多细节,但听起来你在第一种情况下使用单向通信 - 即客户端写入,然后再次写入。服务器将以1次读取的形式接收2次写入的原因有很多。缓冲在客户端,无线堆栈(或BES)中的某个地方,在服务器端缓冲。所有这些都是合法的TCP / IP。
在不了解您的解决方案的情况下,您是否考虑过定义一个小协议 - 即客户端在发送第二次写入之前写入一个已知字节或字节(如0字节?)?然后服务器可以读取,然后识别分隔字节,并说“啊哈,这现在是与客户端不同的写入”?
答案 2 :(得分:1)
如前所述,这是节省带宽的预期TCP行为。请注意,传送包TCP会增加大量数据(例如目标端口,序列号,校验和......)。
我建议您在协议中加入更多工作,而不是刷新数据。例如,您可以定义一个标头,其中包含要读取的字节数,然后是有效负载(实际数据)。
以下代码是以字符串编码的协议,其结构为[length]; [data]
StringBuffer headerStr = new StringBuffer();
StringBuffer data = new StringBuffer();
//read header
char headerByte = dataInputStream.readChar();
while (headerByte != ';') {
headerStr.append(headerByte);
headerByte = dataInputStream.readChar();
}
//header has the number of character to read
int header= Integer.parseInt(headerStr.toString());
int bytesReaded = 1;
char dataByte = dataInputStream.readChar();
//we should read the number of characters indicated in the header
while (bytesReaded < header) {
data.append(dataByte);
dataByte = dataInputStream.readChar();
bytesReaded++;
}
答案 3 :(得分:0)
对于第一个查询,我猜您使用的是TCP。如果使用UDP,则服务器将按您想要的顺序读取数据包。
你能否对第二个问题更清楚/更精细?
答案 4 :(得分:0)
我会尝试明确告诉Connector.open将流打开为read_write。然后我会确保在每次与服务器通信后刷新连接。
SocketConnection connection = (SocketConnection) Connector.open(url, Connector.READ_WRITE);
OutputStream out = connection.openOutputStream();
// ... write to server
out.flush()
答案 5 :(得分:0)
我得到了一个克服的解决方案来提取字符串
在发件人设备上
在收件人设备上