OutputStream.write()成功,但此数据未送达 [英] OutputStream.write() successful but the data is not delivered

查看:960
本文介绍了OutputStream.write()成功,但此数据未送达的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写一个插座一个很奇怪的行为。 在我的移动客户端我使用的是初始化的插槽如下:

I have a very strange behaviour during writing to a socket. In my mobile client I'm using a socket which is initialized as follows:

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

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

然后定期(每60秒),我阅读和写一些数据,这个​​插座(在code这里是一个有点简单):

then periodically (every 60 seconds) I read and write some data to this socket (the code here is a little bit simplified):

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次)我的服务器不接收数据。我的客户端日志是这样的:

And it works. But... Sometimes (very infrequently, maybe 1 or 2 times per day) my server don't receive data. My client log looks like:

Written A
Written B
Written C
Written D
Written E

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

and so on. But on the server side it looks like:

Received A
Received E

B,C没有接收D个数据记录,尽管事实是在客户端,它看起来像所有数据被发送,没有任何例外!

B,C,D data records were not received, despite of fact that on the client side it looks like all data was sent without any exceptions!

这样的差距可以是小(2-3分钟),这是不是很糟糕,但有时也可以是非常大的(1-2小时= 60-120次),它是真正为我的客户一个问题。

Such gaps can be small (2-3 minutes) which is not very bad, but sometimes they can be very big (1-2 hours = 60-120 cycles) and it is really a problem for my customers.

我真的不知道有什么可以是错误的。该数据似乎是由客户端被发送,但它从未到达在服务器端。我检查它也有一个代理。

I really have no idea what can be wrong. The data seems to be sent by client, but it never arrives on the server side. I've checked it also with a proxy.

我只有日志,我无法重现此问题(但它发生在我的客户,每天一个以上的时间),并在日志有时我看到连接异常而破SENDTO失败:ECONNRESET(连接由同行复位)。之后,该程序将关闭套接字,重新初始化它:

I have only logs and I can't reproduce this issue (but it happens to my customer more then one time every day) and in logs sometimes I see that the connection is broken with an Exception "sendto failed: ECONNRESET (Connection reset by peer)". After that the program closes the socket, reinitializes it:

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

// reinitialize
initSocket();

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

and tries to write the data again as described above. Then I see the problem: connection established, writing successful, but NO DATA arrived on the server!

可能是它是与ECONNRESET可能是没有,但我想提一提这个,因为可能是很重要的。

May be it has something to do with ECONNRESET may be not, but I want to mention this because may be it is important.

我会很感激的任何想法和建议。

I would be very grateful for any ideas and tips.

P.S。也许它起着一定的作用:客户端code被移动(这是在汽车)的Andr​​oid移动设备上运行。互联网连接通过GPRS建立。

P.S. Maybe it plays some role: the client code runs on an Android mobile device which is moving (it is in a car). The internet connection is established through GPRS.

UPD:我可以重现它!至少部分地(客户端发送A,B,C,D,E和服务器只接收A)。它发生的每一次的话:

UPD: I can reproduce it! At least partially (the client send A,B,C,D,E and the server receives only A). It happens every time if:

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

  1. The connection is established, the client reads and writes -> OK

的连接丢失(我关掉我的无线路由器:)),我成了IOException异常,我关闭了流和插座 - >确定

The connection is lost (I turn off my WLAN router :)), I became IOException, I close the streams and socket -> OK

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

I turn on my router, the connection is back, I initialize the socket again, the program executes write() without exceptions, but... no data arrives at the server.

顺便说一句,因为连接回来用()返回始终为0。

BTW since the connection is back again available() returns always 0.

推荐答案

这种奇怪​​的行为的原因是服务器端的一个未关闭套接字。我可以用小的客户端和服务器复制它。这两个由几行code,它执行以下操作:

The cause of this strange behavior was a not closed socket on the server side. I could reproduce it with small client and server. Both consist of couple of lines of code, which do the following:

  1. 连接到服务器
  2. 模拟死点(如关闭您的WiFi)
  3. 关闭套接字在客户端
  4. 请不要合上服务器端插座
  5. 在打开你的无线
  6. 建立从客户端的新连接
  7. 写数据到这个连接

瞧!客户端将数据写入没有任何错误,但服务器没有收到它...

Voila! The client writes data without any errors, but the server doesn't receive it...

但是,如果该服务器过于关闭套接字,那么服务器可以读取该数据。因此该解决方案应该是在服务器端在超时后关闭套接字。

But if the server closes the socket too, then the server can read this data. So the solution should be to close the socket after a timeout on the server side.

不幸的是在我的情况下,它是不可行的,因为服务器是一个专有的第三方软件。

Unfortunately in my case it is not viable, because the server is a proprietary third-party software.

这篇关于OutputStream.write()成功,但此数据未送达的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆