JAVA 判断Socket 远程端是否断开连接
最近在做项目的时候,遇到这样一个问题,如何判断 Socket 远程端连接是否关闭,如果关闭的话,就要重建连接Socket的类提供了一些已经封装好的方法, 如 isClosed()、isConnected()、isInputStreamShutdown()、isOutputStreamShutdown()等,在测试时发现,这些方法都是本地端的状态,无法判断远端是否已经断开连接。
其实在socket类中有一个方法sendUrgentData,它会往输出流发送一个字节的数据,只要对方Socket的SO_OOBINLINE属性没有打开,就会自动舍弃这个字节(在Java 中是抛出异常),而SO_OOBINLINE属性默认情况下就是关闭的。
以下是示例代码仅供参考:
- public class Nksocket extends Thread{
- public String ip=null;//连接服务器的IP
- public Integer port=null;//连接服务器的端口
- private Socket socket=null;//套节字对象
- private boolean close = false; // 关闭连接标志位,true表示关闭,false表示连接
- private Integer sotimeout=1*1*10;//超时时间,以毫秒为单位
- //------------------------------------------------------------------------------
- public Nksocket(){
- init();
- }
- public Nksocket(String ip,Integer port){
- setIp(ip);
- setPort(port);
- init();
- }
- /**
- * 初始化socket对象
- */
- public void init(){
- try {
- InetAddress address = InetAddress.getByName(getIp());
- socket = new Socket(address,getPort());
- socket.setKeepAlive(true);//开启保持活动状态的套接字
- socket.setSoTimeout(sotimeout);//设置超时时间
- close=!Send(socket,"2");//发送初始数据,发送成功则表示已经连接上,发送失败表示已经断开
- }catch(UnknownHostException e) {
- e.printStackTrace();
- }catch(IOException e){
- e.printStackTrace();
- }
- }
- /**
- * 读数据线程
- */
- public void run() {
- while(true){
- //---------读数据---------------------------
- close = isServerClose(socket);//判断是否断开
- if(!close){//没有断开,开始读数据
- String readtext = ReadText(socket);
- if(readtext!=null && readtext.trim().length()>0){
- System.out.println("读取数据:"+readtext);
- }
- }
- //---------创建连接-------------------------
- while(close){//已经断开,重新建立连接
- try{
- System.out.println("重新建立连接:"+getIp()+":"+getPort());
- InetAddress address = InetAddress.getByName(getIp());
- socket = new Socket(address,getPort());
- socket.setKeepAlive(true);
- socket.setSoTimeout(sotimeout);
- close = !Send(socket,"2");
- System.out.println("建立连接成功:"+getIp()+":"+getPort());
- }catch(Exception se){
- System.out.println("创建连接失败:"+getIp()+":"+getPort());
- close=true;
- }
- }
- }
- }
- /**
- * 发送数据,发送失败返回false,发送成功返回true
- * @param csocket
- * @param message
- * @return
- */
- public Boolean Send(Socket csocket,String message){
- try{
- PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
- out.println(message);
- return true;
- }catch(Exception se){
- se.printStackTrace();
- return false;
- }
- }
- /**
- * 读取数据,返回字符串类型
- * @param csocket
- * @return
- */
- public String ReadText(Socket csocket){
- try{
- csocket.setSoTimeout(sotimeout);
- InputStream input = csocket.getInputStream();
- BufferedReader in = new BufferedReader(new InputStreamReader(input));
- char[] sn = new char[1000];
- in.read(sn);
- String sc = new String(sn);
- return sc;
- }catch(IOException se){
- return null;
- }
- }
- /**
- * 判断是否断开连接,断开返回true,没有返回false
- * @param socket
- * @return
- */
- public Boolean isServerClose(Socket socket){
- try{
- socket.sendUrgentData(0xFF);//发送1个字节的紧急数据,默认情况下,服务器端没有开启紧急数据处理,不影响正常通信
- return false;
- }catch(Exception se){
- return true;
- }
- }
- /**
- * 测试
- * @param ags
- */
- public static void main(String[] ags){
- Nksocket nksocket = new Nksocket("127.0.0.1",8090);
- nksocket.start();
- }
- //------------------------------------------------------------------------------
- public String getIp() {
- return ip;
- }
- public void setIp(String ip) {
- this.ip = ip;
- }
- public Integer getPort() {
- return port;
- }
- public void setPort(Integer port) {
- this.port = port;
- }
- }
参考资料:
http://blog.csdn.net/xyz_lmn/article/details/6146749
http://ivan4126.blog.163.com/blog/static/20949109220135284278806/
JAVA 判断Socket 远程端是否断开连接的更多相关文章
- 在HTTP通讯过程中,是客户端还是服务端主动断开连接?
比如说:IE访问IIS,获取文件,肯定是要建立一个连接,这个连接在完成通讯后,是客户端Close了连接,还是服务端Close了连接.我用程序测模拟IE和IIS,都没有收到断开连接的消息,也就是都没有触 ...
- Java中使用Socket连接判断Inputstream结束,java tcp socket服务端,python tcp socket客户端
最近在试着用java写一个socket的服务器,用python写一个socket的客户端来完成二者之间的通信,但是发现存在一个问题,服务器方面就卡在读取inputsream的地方不动了,导致后面的代码 ...
- 判断网络远端服务器是否断开连接(心跳连接:socket.sendUrgentData)
1.socket类的方法isClosed().isConnected().isInputStreamShutdown().isOutputStreamShutdown()等,这些方法都是本地端的状态, ...
- java判断是移动端还是pc端
// \b 是单词边界(连着的两个(字母字符 与 非字母字符) 之间的逻辑上的间隔), // 字符串在编译时会被转码一次,所以是 "\\b" // \B 是单词内部逻辑间隔(连着的 ...
- JAVA ANDROID SOCKET通信检测(SERVER)连接是否断开
Pre 解决思路 代码后记: 客户端app上的部分代码 调用: 服务器上: 客户端判断服务器是否还活着代码: PRE 在利用socket写通讯程序的时候,想检测服务器是否还活着. 从网上找了很多资料, ...
- java socket 判断Socket连接失效
要判断socket连接链路是否可用时,不能通过socket.isClosed() 和 socket.isConnected() 方法判断,要通过心跳包 socket.sendUrgentData(0x ...
- C#socket通信时,怎样判断socket双方是否断开连接
我在Server端new了一个socket,然后bind,开了一个线程来accept前来连接的client,每接到一个client前来连接就新开一个线程和它进行通信.我把Server端得到的socke ...
- tcp 服务端如何判断客户端断开连接
一篇文章: 最近在做一个服务器端程序,C/S结构.功能方面比较简单就是client端与server端建立连接,然后发送消息给server.我在server端会使用专门的线程处理一条socket连接 ...
- Tcp服务端判断客户端是否断开连接
今天搞tcp链接弄了一天,前面创建socket,绑定,监听等主要分清自己的参数,udp还是tcp的.好不容易调通了,然后就是一个需求,当客户端主动断开连接时,服务端也要断开连接,这样一下次客户端请求链 ...
随机推荐
- 获取ORACLE数据库的构建信息
首先连接到数据库,获取ORACLE数据库的基本信息: C:\USERS\ADMINISTRATOR>SQLPLUS/NOLOG SQL*PLUS: RELEASE 10.2.0.3.0 - PR ...
- Swift笔记
最近从Xcode6 beta4开始到现在的Xcode6.0.1,使用Swift一段时间了,Swift大体来说,语法与java.c++比较接近,相比objective-c要友好多了,也更容易上手,这里记 ...
- bzoj 3531 旅行
动态开点线段树+树链剖分 对于每一种宗教信仰都开一颗线段树 空间: QlogN 即每一次修改都只会改变logN 个点 时间 O(QlogN) naive题 边没有开两倍 QAQ bzoj 35 ...
- Codeforces Round #167 (Div. 2)
C. Dima and Staircase 线段树维护区间最大值. D. Dima and Two Sequences 由于模数不一定为质数,所以通过拆分质因数来做阶乘取模. E. Dima and ...
- ns115 step by step
一,安装环境: sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev lib ...
- 另类vs2015+xamarin 的android界面乱码 解决
text.Text += "验证key 验证出错! 请在 AndroidManifest.xml 文件中检查 key 设置"; 代码就上面一行,单步走之前text.Text里面是汉 ...
- (转)Image Segmentation with Tensorflow using CNNs and Conditional Random Fields
Daniil's blog Machine Learning and Computer Vision artisan. About/ Blog/ Image Segmentation with Ten ...
- Lua词汇约定
Lua的标识符包含数字,字母以及下划线,数字不能作为标识符的开头. and break do else elseif end false for function goto if in local n ...
- Ninject使用介绍
#region 第二种写法 /// <summary> /// using(IKernel tKernel=new StandardKernel(new PeoKernelServer() ...
- sql server2008 检查是否需要挂起计算机重新启动。挂起重新启动会导致安装程序失败。
解决方法: 1.如果重新启动后,一样无效, 2.那么就进入注册表编辑器,通过修改注册表的方法来解决.除了删除SQL安装时遗留下的LJ文件,还必须进行以下操作: 在"开始"-&quo ...