Android-Socket通信

Android-Socket通信

Socket通信的应用

编写一个Socket连接的工具类SocketConnect,其中handle是用来传递连接状态的。

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;


import android.os.Handler;

/**
 * @author ${M.xang} 创建时间:2018-5-28 上午9:51:14 类描述 : socket连接类
 */
public class SocketConnect {
    private static SocketConnect socketConnect;
    private Socket socket;
    private Handler mHandler;
    private OutputStream out = null;
    private InputStream in = null;
    /** 接收tcp数据 */
    private byte[] dataReceive = null;
    private boolean isConnect = false;// 服务端连接是否已经建立
    private boolean receiveFlag = true;// 接收数据线程标记
    /**
     * 获取单例
     * @return
     */
    public static SocketConnect getInit() {
	if (socketConnect == null) {
	    socketConnect = new SocketConnect();
	}
	return socketConnect;
    }

    private SocketConnect() {
	receiveFlag = true;
    }

    public Socket getSocket() {
	return socket;
    }

    public byte[] getDataReceive() {
	return dataReceive;
    }

    public void setDataReceive(byte[] dataReceive) {
	this.dataReceive = dataReceive;
    }

    /**
     * Socket是否连接标记
     * @return
     */
    public boolean getConnectState() {
    	return isConnect;
    }
    /**
     * 在每进入一个Activity后,要先传送本界面使用的Handler类型实例
     * @param mainHandler
     */
    public void setHandler(Handler mainHandler) {
    	mHandler = mainHandler;
    }

    /**
     * 建立服务器连接
     * 
     * @param IP
     *            String IP地址
     * @param port
     *            int 端口号
     */
    public void setConnect(final String IP, final int port) {
    	new Thread(new Runnable() {
    	    @Override
    	    public void run() {
    		try {
    		    closeSocket();
    		    if (socket == null) {
    		        socket = new Socket();
    		        socket.connect(new InetSocketAddress(IP, port), 15000);
		        Thread.sleep(50, 0); // 实际中刚连上后发数据需要一定延时 确保双方链接初始化完成
	            }
		    if (out == null) {
			out = new DataOutputStream(socket.getOutputStream());
		    }
		    if (in == null) {
		        in = new DataInputStream(socket.getInputStream());
		    }
		    isConnect = true;
		    mHandler.sendEmptyMessage(AppData.LAN_CONNECT); // 将标题颜色设为绿色
		    receiveFlag = true;
		    Thread.sleep(50);
		    receiveData();// 接收线程
		} catch (SocketTimeoutException se) {
		    // 超时,红色点闪烁
		    mHandler.obtainMessage(AppData.LAN_TIME_OUT).sendToTarget();
		} catch (IOException e) {
		    // 网络中断连接,红色点闪烁
		    mHandler.obtainMessage(AppData.LAN_INPERRUPT).sendToTarget();
		    e.printStackTrace();
		} catch (InterruptedException e) {
		    e.printStackTrace();
		}
        }
    }).start();
}

    /**
     * 关闭socket
     */
    public void closeSocket() {
        try {
	    if (in != null) {
	        in.close();
		in = null;
	    }
	    if (out != null) {
		out.close();
		out = null;
	    }
	    if (socket != null) {
		socket.close();
		socket = null;
	    }
	    isConnect = false;
	    receiveFlag = false;
	} catch (IOException e) {
	    e.printStackTrace();
	}
    }
	
    /**
     * 发送数据
     * @param controlId
     * @param IP
     * @param data
     */
    public void sendData(final int controlId, final byte[] IP, final byte[] data) {
        new Thread(new Runnable() {
	    public void run() {
		    try {
			byte[] temp = SocketUtil.getInit().makePocket(controlId, IP, data);
			if (out != null) {
			    out.write(temp);
			    out.flush();
			}
		    } catch (Exception e) {
			e.printStackTrace();
		    }
	    }
	}).start();
    }

    /**
     * 接收数据线程
     */
    public void receiveData() {
        new Thread(new Runnable() {
	    public void run() {
	        try {
		    while (receiveFlag) {
		        if (isConnect) {
			    Thread.sleep(20);
			    if (in != null) {
			        if (in.available() > 0) {
				    Thread.sleep(100);
				    int backLength = in.available();
				    dataReceive = new byte[backLength];
				    int len = 0;
				    while (len < backLength) {
				        len += in.read(dataReceive, len, backLength - len);
                                    }
				    setDataReceive(dataReceive);
				    MainActivity.ProcessReceievData();// 接收到的数据返回到mainActivity处理
			        }
			    }
		        }
		    }
		} catch (Exception e) {
		    e.printStackTrace();
		}
       	    }
        }).start();
    }
}

在Activity中的调用:

首先获取Socket对象,如果没有建立连接,则打开连接线程,建立Socket连接。

/**
	 * 建立Socket连接
	 */
	private void initSocket() {
		ip = SPUtil.getIP();
		port = SPUtil.getPort();
		socketConnect = SocketConnect.getInit();// 获取Socket单例对象
		socketConnect.setHandler(mainHandler);
		if (!socketConnect.getConnectState()) {
			// 如果Socket没有连接
			connectThread();
		}
		// TODO 心跳包 68 17 20 30 20 40 02 68 00 00 99 16
		heartThread();
	}

connectThread():开辟个线程建立连接

/**
	 * 建立服务器Socket连接
	 */
	private void connectThread() {
		new Thread(new Runnable() {
			public void run() {
				try {
					socketConnect.setConnect(ip, port);
					Thread.sleep(3000);
					if (socketConnect.getConnectState()) {
						mainHandler.sendEmptyMessage(AppData.LAN_CONNECT); // 将标题颜色设为绿色
						localIp = SystemUtil.getIP(MainActivity.this);
					} else {
						mainHandler.sendEmptyMessage(6); // 将标题颜色设为红色
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}).start();
	}

heartThread():心跳,每5秒发送一次心跳包,没有接收到服务端返回的心跳应答数据,三次没接收到则进行重新建立连接。

/**
	 * 开启心跳包的线程
	 */
	private void heartThread() {
		new Thread(new Runnable() {
			int heartCount = 0;// 接收心跳的等待次数,一次5秒

			public void run() {
				try {
					while (true) {
						Thread.sleep(1000);
						if (heartCount == 3) {
							connectThread();// 重新建立Socket连接
							heartCount = 0;
							heartFlag = true;
							heartThread();
							break;
						}
						if (socketConnect.getSocket() != null) {
//							Log.w("心跳包数据", "-----发送心跳数据=-----" + heartCount);
							SocketUtil.getInit().sendHeartData(localIp);// 发送心跳数据
						}
						if (heartFlag) {
							heartCount = 0;
							if (socketConnect.getConnectState()) {
								mainHandler.sendEmptyMessage(AppData.LAN_CONNECT); // 将标题设为绿色
							} else {
								mainHandler.sendEmptyMessage(6); // 将标题颜色设为红色
							}
						} else {
							mainHandler.sendEmptyMessage(6); // 将标题颜色设为红色
						}
						heartCount++;
						heartFlag = false;
						Thread.sleep(4000);
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}).start();
	}

mainHandler:用来展示连接状态

/**
	 * 网络连接提示语
	 */
	private Handler mainHandler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case AppData.LAN_CONNECT:
//				MyToast.showToast(MainActivity.this, "连接成功!");
				img.setImageDrawable(getResources().getDrawable(R.drawable.blue));// 连接成功,蓝色点闪烁
				break;
			case AppData.LAN_TIME_OUT:
				connectThread();// 连接服务器
				MyToast.showToast(MainActivity.this, "连接超时!");
				img.setImageDrawable(getResources().getDrawable(R.drawable.red));// 连接超时,红色点闪烁
				break;
			case AppData.LAN_INPERRUPT:
				MyToast.showToast(MainActivity.this, "连接异常,请检查网络连接!");
				img.setImageDrawable(getResources().getDrawable(R.drawable.red));// 连接异常,红色点闪烁
				break;
			case 6:// 连接断开(心跳包不正常),将标题设为红色
				img.setImageDrawable(getResources().getDrawable(R.drawable.red));// 连接异常,红色点闪烁
				break;
			default:
				break;
			}
		};
	};

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值