socket开发注意点

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hgxbra/article/details/56011335


一 
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会变成半关闭状态,发送并不会报异常,检测连接的最有效办法是发送心跳包,每个心跳都记录时间,当回应的时间超过规定时间,当作掉线处理

猜你喜欢

转载自blog.csdn.net/hgxbra/article/details/56011335
今日推荐