阅读背景:

socket 通讯检测客户端非正常断线。

来源:互联网 
package com.ist.socket;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;

/**
 *  Socket收发器 通过Socket发送数据,并使用新线程监听Socket接收到的数据
 * @author songqiang
 * @createtime 2015-12-15
 */
public abstract class MediaTransceiver implements Runnable{

	protected Socket socket;
	protected InetAddress addr;
	protected String falshId;
	protected DataInputStream in;
	protected DataOutputStream out;
	private boolean runFlag;
	//是否在线标识
	private boolean onlineFlag;
	/**
	 * 服务器端实例化
	 * @param socket
	 */
	public MediaTransceiver(Socket socket) {
		this.socket = socket;
		this.addr = socket.getInetAddress();
	}
	/**
	 * 监听Socket接收的数据(新线程中运行)
	 */
	@Override
	public void run() {
		try {
			//socket输入流
			in = new DataInputStream(this.socket.getInputStream());
			//socket输出流
			out = new DataOutputStream(this.socket.getOutputStream());
		} catch (IOException e) {
			e.printStackTrace();
			runFlag = false;
		}
		//无限接收服务端信息,直到连接端口
		while(runFlag){
			try{
				//接受数据
				final String s = in.readUTF();
				if(s.equals("1")){
					onlineFlag = true;
				}
				this.onReceive(addr, s);
			}catch(EOFException e){
				
			}catch (IOException e){
				// 连接被断开(被动)
				runFlag = false;
			}
		}
		//断开连接
		try {
			in.close();
			out.close();
			socket.close();
			in = null;
			out = null;
			socket = null;
		} catch (IOException e) {
			e.printStackTrace();
		}
		this.onDisconnect(addr);
	}
	static void delay() {
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 开启Socket收发
	 * 如果开启失败,会断开连接并回调{@code onDisconnect()}
	 */
	public void start(){
		runFlag = true;
		new Thread(this).start();
	}

	/**
	 * 断开连接(主动)
	 * 连接断开后,会回调{@code onDisconnect()}
	 */
	public void stop(){
		runFlag = false;
		try {
			socket.shutdownInput();
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	//向服务器发送falshId
	public void sendFalshId(String falshId){
		if(out!=null){
			try{
				send("falshId:"+falshId);
			}catch(Exception e){
				e.printStackTrace();
			}
		}else{
			if(runFlag){
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				sendFalshId(falshId);
			}
		}
	}
	/**
	 * 向服务端发送信息
	 * @param s
	 * @return
	 */
	public boolean send(String s){
		if(out!=null){
			try{
				out.writeUTF(s);
				out.flush();
				return true;
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		return false;
	}
	/**
	 * 检查socket是否执行
	 */
	public void checkOnLine(){
		send("0");
		onlineFlag = false;
		//线程等待onlineFlag标识是否改变
		Thread checkThread = new Thread(new Runnable() {		
			@Override
			public void run() {
				delay();
				//标识没有改变则判断为离线
				if(!onlineFlag){
					stop();
				}
			}
		});
		checkThread.start();
	}
	/**
	 * 获取连接到的Socket地址
	 * 
	 * @return InetAddress对象
	 */
	public InetAddress getInetAddress() {
		return addr;
	}
	
	public String getFalshId() {
		return falshId;
	}

	public void setFalshId(String falshId) {
		this.falshId = falshId;
	}
	//-------------------------------实例化时实现---------------------------
	/**
	 * 接收到数据
	 * 注意:此回调是在新线程中执行的
	 * @param addr 连接到的Socket地址
	 * @param s:收到的字符串
	 */
	public abstract void onReceive(InetAddress addr, String s);

	/**
	 * 连接断开
	 * 注意:此回调是在新线程中执行的
	 * @param addr
	 * 连接到的Socket地址
	 */
	public abstract void onDisconnect(InetAddress addr);
	
}
package com.ist.socket;

import 



你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: