I have an application handling several Java socket connections to different kinds of remote machines (some PCs, others are embedded devices). The开发者_StackOverflowse sockets and streams should not close indefinitely except for a very good reason (e.g. crash of remote system).
I frequently encounter an issue where the input stream ends unexpectedly, without any reason (value is -1), i.e. the remote machine does not signal a connection abort. But when I discard these -1 reads and continue reading from the stream, the remote machine actually sends new data later. This can go on for a very long time. I also can still write to the output stream too.
In the current situation, I have the choice between treating -1 as end of stream and close the socket (with false positives), or ignore -1 input and risk not being notified of real disconnects.
I haven't been able to create a working example of this issue and the problems appear randomly.
Any ideas what's wrong?
Edited to add: The Java endpoint is a rewrite of an existing VB application that did not have these problems (at least to my knowledge).
If you get -1 meaning the stream is closed then you cannot read beyond this and find more data. Once a stream is closed, it cannot be read again.
It sounds like you are performing a read() and casting this to a byte. This means you cannot tell the difference between a 255 value (which you can read beyond) and a -1 stream closed value (which you cannot)
Check the routers inbewteen. It is common for cheap routers, especially those doing NAT, that they clean up their connection tables once in a while, causing your connections to go stale.
In any case, your application should be robust against these things (they will happen again), and you may help it by sending packets without business value across the wire regularily.
Have you ever used Wireshark? Its very easy to set up and might let you know if there's anything unusual going on with the TCP conversation when this happens.
I had something similar to your issue once and I solved it by sending a ping message every minute between server and client. (It later turned out that a firewall issue was occasionally closing half of the connection if no traffic had gone over it for 10 minutes.)
I know that you're doing KeepAlive messages but its possible that something along the route is not supporting them. If you send your own ping message with a few bytes, you can be sure. I'd capture the actual packets on both ends with Wireshark in either case to make sure that the KeepAlive messages are really getting all the way to the endpoint.
There is apparently some network issues in your environment, and you can try and track them down, but for the time being it's safer to close the stream and re-open it. That's what API assumes.
精彩评论