一
socket自带两个通道, 一个接收,一个发送, 互不影响, 通讯过程中,可关闭其中一个,或两个一起关闭
二 isClosed()与isConnected
isClosed()方法来判断某个Socket对象是否处于关闭状态, 但并不是指连接是否关闭, 当然,如果对象关闭了,连接自然也就关闭, 但是连接关闭了,对象并不一定是关闭
isConnected()方法来判断Socket对象是否曾经连接成功过, 此英文是过去式, 并不代表当前的真实连接状态。
即使现在isClose返回true,isConnected仍然返回true。因此,要判断当前的Socket对象是否处于连接状态,必须同时使用isClosed()和isConnected()方法,即只有当isClosed()返回false,isConnected()返回true的时候Socket对象才处于连接状态。
据分析,两方法合并最有效的用于主动请求,即客户端, 服务端accept()得到的 socket, isConnected肯定是true, 而isClosed并不能代表真实的连接是否关闭
当其中一方连接突然断开,或意外断开时, 会报Connection reset的错误消息,可拦截此消息来提示连接已断开
三 关闭连接
1. socket.close() 关闭连接,
2. 当Socket类的InputStream和OutputStream只有一个关闭,就是半关闭状态。
3. socket.shutdownOutput() ,要告诉对方已发送结束, 并且关闭发送通道,
四 阻塞
socket.getIntputStream() 的 read() 会阻塞, 但执行了available() 之后, 下一次的read将不阻塞的从这个输入流读取(或跳过)的估计剩余字节数
InputStream is = this.clientSocket.getInputStream();
int c = is.available();
byte[] b = new byte[c>1024?c:1024]; //由于是估计的剩余字节数, 所以保险一点
int l = 0;
l = is.read(b);//由于available()只用于下一次不阻塞,所以这里不用while ((l=xx) != -1), 否则会阻塞
strb.append(new String(b,0,l));
五 超时
setSoTimeout(int); 此超时的方法并不是值连接超时, 只是read()超时, 即在规定的时间内, 还没有read()到数据,就报SocketException超时错误, 而socket仍然是有效的, 此超时记录还是累加的,假设超时定了5秒,每read()一次都用2秒, 第三次就会超时,此方法可以理解为定义read阻塞超时,在whlie里面定义,可以起到部分作用
六,判断连接
当客户端意外端口时, 有时socket会变成半关闭状态,发送并不会报异常,检测连接的最有效办法是发送心跳包,每个心跳都记录时间,当回应的时间超过规定时间,当作掉线处理