Android的TCP Socket连接组件

Android的TCP Socket连接组件

https://github.com/Sopage/android-network

https://github.com/Sopage/DreamSocket

package android.net.tcp;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;

/**
 * Socket连接操作类
 * 
 * @author Esa
 */
public class SocketBase {

	private Socket mSocket;// socket连接对象
	private DataOutputStream out;
	private DataInputStream in;// 输入流
	private SocketCallback callback;// 信息回调接口
	private int timeOut = 1000 * 30;

	/**
	 * 构造方法传入信息回调接口对象
	 * 
	 * @param sdi
	 *            回调接口
	 */
	public SocketBase(SocketCallback callback) {
		this.callback = callback;
	}

	/**
	 * 连接网络服务器
	 * 
	 * @throws UnknownHostException
	 * @throws IOException
	 */
	public void connect(String ip, int port) throws Exception {
		mSocket = new Socket();
		SocketAddress address = new InetSocketAddress(ip, port);
		mSocket.connect(address, timeOut);// 连接指定IP和端口
		if (mSocket.isConnected()) {
			out = new DataOutputStream(mSocket.getOutputStream());// 获取网络输出流
			in = new DataInputStream(mSocket.getInputStream());// 获取网络输入流
			callback.connected();
		}
	}

	public void setTimeOut(int timeOut) {
		this.timeOut = timeOut;
	}

	/**
	 * 返回连接服是否成功
	 * 
	 * @return
	 */
	public boolean isConnected() {
		if(mSocket != null){
			return mSocket.isConnected();
		}
		return false;
	}

	/**
	 * 发送数据
	 * 
	 * @param buffer
	 *            信息字节数据
	 * @throws IOException
	 */
	public void write(byte[] buffer) throws IOException {
		if (out != null) {
			out.write(buffer);
			out.flush();
		}
	}

	/**
	 * 断开连接
	 * 
	 * @throws IOException
	 */
	public void disconnect() {
		try {
			if (mSocket != null) {
				if (!mSocket.isInputShutdown()) {
					mSocket.shutdownInput();
				}
				if (!mSocket.isOutputShutdown()) {
					mSocket.shutdownOutput();
				}
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
				mSocket.close();// 关闭socket
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			callback.disconnect();
			out = null;
			in = null;
			mSocket = null;// 制空socket对象
		}
	}

	/**
	 * 读取网络数据
	 * 
	 * @throws IOException
	 */
	public void read() throws IOException {
		if (in != null) {
			byte[] buffer = new byte[1024*1];// 缓冲区字节数组,信息不能大于此缓冲区
			byte[] tmpBuffer;// 临时缓冲区
			int len = 0;// 读取长度
			while ((len = in.read(buffer)) > 0) {
				tmpBuffer = new byte[len];// 创建临时缓冲区
				System.arraycopy(buffer, 0, tmpBuffer, 0, len);// 将数据拷贝到临时缓冲区
				callback.receive(tmpBuffer);// 调用回调接口传入得到的数据
				tmpBuffer = null;
			}
		}
	}
}
package android.net.tcp;

import java.util.Vector;

/**
 * 连接服务器线程类
 * 
 * @author Esa
 */
public class SocketConnect implements Runnable {

	private boolean isConnect = false;// 是否连接服务器
	private boolean isWrite = false;// 是否发送数据
	private static final Vector<byte[]> datas = new Vector<byte[]>();// 待发送数据队列
	private SocketBase mSocket;// socket连接
	private WriteRunnable writeRunnable;// 发送数据线程
	private String ip = null;
	private int port = -1;

	/**
	 * 创建连接
	 * 
	 * @param callback
	 *            回调接口
	 */
	public SocketConnect(SocketCallback callback) {
		mSocket = new SocketBase(callback);// 创建socket连接
		writeRunnable = new WriteRunnable();// 创建发送线程
	}

	@Override
	public void run() {
		if (ip == null || port == -1) {
			throw new NullPointerException("not set address");
		}
		isConnect = true;
		while (isConnect) {
			synchronized (this) {
				try {
					mSocket.connect(ip, port);// 连接服务器
				} catch (Exception e) {
					try {
						mSocket.disconnect();// 断开连接
						this.wait(6000);
						continue;
					} catch (InterruptedException e1) {
						continue;
					}
				}
			}
			isWrite = true;// 设置可发送数据
			new Thread(writeRunnable).start();// 启动发送线程
			try {
				mSocket.read();// 获取数据
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				writeRunnable.stop();
				mSocket.disconnect();
			}
		}
	}

	/**
	 * 关闭服务器连接
	 */
	public synchronized void disconnect() {
		isConnect = false;
		this.notify();
		resetConnect();
	}

	/**
	 * 重置连接
	 */
	public void resetConnect() {
		writeRunnable.stop();// 发送停止信息
		mSocket.disconnect();
	}

	/**
	 * 向发送线程写入发送数据
	 */
	public void write(byte[] buffer) {
		writeRunnable.write(buffer);
	}

	/**
	 * 设置IP和端口
	 * 
	 * @param ip
	 * @param port
	 */
	public void setRemoteAddress(String host, int port) {
		this.ip = host;
		this.port = port;
	}

	/**
	 * 发送数据
	 */
	private boolean writes(byte[] buffer) {
		try {
			mSocket.write(buffer);
			return true;
		} catch (Exception e) {
			resetConnect();
		}
		return false;
	}

	/**
	 * 发送线程
	 * 
	 * @author Esa
	 */
	private class WriteRunnable implements Runnable {

		@Override
		public void run() {
			System.out.println(">TCP发送线程开启<");
			while (isWrite) {
				synchronized (this) {
					if (datas.size() <= 0) {
						try {
							this.wait();// 等待发送数据
						} catch (InterruptedException e) {
							continue;
						}
					}
					while (datas.size() > 0) {
						byte[] buffer = datas.remove(0);// 获取一条发送数据
						if (isWrite) {
							writes(buffer);// 发送数据
						} else {
							this.notify();
						}
					}
				}
			}
			System.out.println(">TCP发送线程结束<");
		}

		/**
		 * 添加数据到发送队列
		 * 
		 * @param buffer
		 *            数据字节
		 */
		public synchronized void write(byte[] buffer) {
			datas.add(buffer);// 将发送数据添加到发送队列
			this.notify();// 取消等待
		}

		public synchronized void stop() {
			isWrite = false;
			this.notify();
		}
	}
}
package android.net.tcp;

/**
 * 获取网络数据回调类
 * 
 * @author Esa
 * 
 */
public abstract interface SocketCallback {
	
	/**
	 * 当建立连接是的回调
	 */
	public abstract void connected();

	/**
	 * 当获取网络数据回调接口
	 * 
	 * @param buffer
	 *            字节数据
	 */
	public abstract void receive(byte[] buffer);

	/**
	 * 当断开连接的回调
	 */
	public abstract void disconnect();

}
//使用方法
		SocketConnect connect = new SocketConnect(new SocketCallback() {
			
			@Override
			public void receive(byte[] buffer) {
				System.out.println("Server Message :" + new String(buffer));
			}
			
			@Override
			public void disconnect() {
				
			}
			
			@Override
			public void connected() {
				
			}
		});
		connect.setRemoteAddress("localhost", 11011);
		new Thread(connect).start();
		for(int i=0; i<100; i++){
			connect.write("test".getBytes());
			Thread.sleep(1000);
		}

 

转载于:https://my.oschina.net/hes/blog/158404

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/110030.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 面试官:请你谈谈Java的类加载过程[通俗易懂]

    面试官:请你谈谈Java的类加载过程[通俗易懂]刚刚走出校门的应届毕业生,如果在去寻求一份Java开发的工作时,你的面试官很有可能一边看着你的简历,一边漫不经心地问你:了解过Java类的加载过程吗?这个时候你一定要注意了,虽然这是一个老生常谈的问题,但是这也是一个非常能够考验你Java功底的问题。如果你答好了,这是你应该的;如果你没答好,那么对不起,面试官心中已经给了你不及格。今天,小编就Java类加载过程这个问题,抛砖引玉,说一下…

    2022年8月11日
    4
  • unity3d百度百科_3d怎么恢复四个界面

    unity3d百度百科_3d怎么恢复四个界面本文介绍了Unity3D界面及游戏对象基本操作。

    2022年8月10日
    5
  • Matlab画图颜色「建议收藏」

    Matlab画图颜色「建议收藏」matlab绘图配色

    2022年5月6日
    284
  • hey,你的CommonJS规范

    hey,你的CommonJS规范

    2021年6月13日
    108
  • Pytorch搭建DenseNet[通俗易懂]

    Pytorch搭建DenseNet[通俗易懂]文章目录DenseNet与ResNeXtDenseNet网络的搭建Growth_rateTransitionLayerBottleneck定义网络小测试问题1训练与测试可视化网络结构DenseNet与ResNeXt首先回顾一下DenseNet的结构,DenseNet的每一层都都与前面层相连,实现了特征重用。下图表示一个DenseBlock如图所示,在一个DenseBlock中,第i层的…

    2022年9月29日
    0
  • springboot跨域携带cookie

    springboot跨域携带cookie解决springboot跨域问题importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.cors.CorsConfiguration;importorg.springframework.web.cors.UrlBasedCorsConfigurationSource;.

    2022年6月22日
    165

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号