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个周期),这确实是我的客户面临的问题。
我真的不知道出了什么问题。数据似乎由客户端发送,但从未到达服务器端。我还使用代理进行了检查。
我只有日志,无法重现此问题(但它每天会多次发生在我的客户身上),有时在日志中我看到连接断开并出现异常“sendto failed: ECONNRESET (Connection reset by peer)”。之后程序关闭套接字并重新初始化:
// close
is.close();
os.close();
socket.close();
// reinitialize
initSocket();
尝试按照上述描述再次写入数据。然后我发现问题:连接建立,写入成功,但服务器上没有任何数据到达!可能与 ECONNRESET 有关,也可能不是,但我想提一下,因为这可能很重要。
对于任何想法和提示,我将非常感激。
P.S.也许它扮演了一些角色:客户端代码运行在正在移动的 Android 移动设备上(即在汽车中)。通过 GPRS 建立互联网连接。
更新:我可以复现它!至少部分地复现(客户端发送 A,B,C,D,E,而服务器只接收到 A)。如果:
建立连接,客户端读取和写入 -> OK
连接丢失(我关闭 WLAN 路由器 :)),我会出现 IOException,我关闭流和套接字 -> OK
我打开路由器,连接恢复,我重新初始化 socket,程序执行 write() 未出现异常,但...没有数据到达服务器。
顺便说一句,由于连接已恢复,available() 总是返回 0。
ByteArrayOutputStream
吗?类似 这样的方式。 - jnthnjns