java socket 判断关闭,Java套接字API:如何判断连接是否已经关闭?

I am running into some issues with the Java socket API. I am trying to display the number of players currently connected to my game. It is easy to determine when a player has connected. However, it seems unnecessarily difficult to determine when a player has disconnected using the socket API.

Calling isConnected() on a socket that has been disconnected remotely always seems to return true. Similarly, calling isClosed() on a socket that has been closed remotely always seems to return false. I have read that to actually determine whether or not a socket has been closed, data must be written to the output stream and an exception must be caught. This seems like a really unclean way to handle this situation. We would just constantly have to spam a garbage message over the network to ever know when a socket had closed.

Is there any other solution?

解决方案

There is no TCP API that will tell you the current state of the connection. isConnected() and isClosed() tell you the current state of your socket. Not the same thing.

isConnected() tells you whether you have connected this socket. You have, so it returns true.

isClosed() tells you whether you have closed this socket. Until you have, it returns false.

If the peer has closed the connection in an orderly way

read() returns -1

readLine() returns null

readXXX() throws EOFException for any other XXX.

A write will throw an IOException: 'connection reset by peer', eventually, subject to buffering delays.

If the connection has dropped for any other reason, a write will throw an IOException, eventually, as above, and a read may do the same thing.

If the peer is still connected but not using the connection, a read timeout can be used.

Contrary to what you may read elsewhere, ClosedChannelException doesn't tell you this. [Neither does SocketException: socket closed.] It only tells you that you closed the channel, and then continued to use it. In other words, a programming error on your part. It does not indicate a closed connection.

As a result of some experiments with Java 7 on Windows XP it also appears that if:

you're selecting on OP_READ

select() returns a value of greater than zero

the associated SelectionKey is already invalid (key.isValid() == false)

it means the peer has reset the connection. However this may be peculiar to either the JRE version or platform.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值