OutputStream.write()成功但数据未传递

时间:2012-10-25 19:52:37

标签: java android network-programming java-io

写入套接字时我有一种非常奇怪的行为。 在我的移动客户端中,我使用的套接字初始化如下:

private void initSocket()
{
    socket = new Socket();
    socket.connect(new InetSocketAddress(host, port));

    os = new DataOutputStream(socket.getOutputStream());
    is = new DataInputStream(socket.getInputStream());
}

然后定期(每60秒)我读取一些数据到这个套接字(这里的代码有点简化):

if(!isSocketInitialized())
{
    initSocket();
}

byte[] msg = getMessage();

os.write(msg);
os.flush();

int bytesAvailable = is.available( );
if(bytesAvailable>0)
{
    byte[] inputBuffer = new byte[bytesAvailable];

    int numRead = is.read(inputBuffer, 0, bytesAvailable);
    processServerReply(inputBuffer, numRead);
}

它有效。但是......有时(很少,每天可能是1或2次)我的服务器不接收数据。我的客户端日志如下:

Written A
Written B
Written C
Written D
Written E

等等。但在服务器端看起来像:

Received A
Received E

未收到B,C,D数据记录,尽管事实上在客户端看起来所有数据都是在没有任何异常的情况下发送的!

这样的间隙可能很小(2-3分钟),这不是很糟糕,但有时它们可​​能非常大(1-2小时= 60-120个周期),这对我的客户来说确实是一个问题。

我真的不知道出了什么问题。数据似乎是由客户端发送的,但它永远不会到达服务器端。我也用代理检查了它。

我只有日志而且我无法重现这个问题(但是我的客户每天都会发生这种情况)并且在日志中有时我会看到连接因异常而被破坏“发送失败:ECONNRESET(连接)由同行重置)“。之后,程序关闭套接字,重新初始化它:

// close
is.close();
os.close();
socket.close();

// reinitialize
initSocket();

并尝试再次写入数据,如上所述。然后我看到问题:建立连接,写入成功,但没有数据到达服务器!

可能与ECONNRESET有关可能不是,但我想提一下,因为它可能很重要。

我会非常感谢任何想法和提示。

P.S。也许它扮演了一些角色:客户端代码运行在移动的Android移动设备上(它在汽车中)。通过GPRS建立互联网连接。


UPD:我可以重现它!至少部分(客户端发送A,B,C,D,E,服务器只接收A)。如果出现以下情况,每次都会发生:

  1. 建立连接,客户端读写 - >确定

  2. 连接丢失(我关闭了我的WLAN路由器:)),我成了IOException,我关闭了流和套接字 - >确定

  3. 我打开路由器,连接回来了,我再次初始化套接字,程序执行write()没有异常,但是......没有数据到达服务器。

  4. BTW,因为连接再次返回available()总是返回0。

1 个答案:

答案 0 :(得分:2)

摆脱available()测试。如果对方想要回复,只需阅读即可。否则,有时您会阅读回复,有时您不会,但您将失去同步。 available()的正确用法非常少,而且不是其中之一。