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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • yolo 实例分割_jacobi椭圆函数

    yolo 实例分割_jacobi椭圆函数Abstract我们提出了一个简单的、完全卷积的实时实例分割模型,在MS-COCO上达到29.8map,在单个TitanXp上以33.5fps的速度进行评估,这比以往任何竞争方法都要快得多。而且,我们只在一个GPU上训练就得到了这个结果。我们通过将实例分割分成两个子任务来实现这一点:(1)生成一组原型掩码;(2)预测每个实例的掩码系数。然后,我们通过将原型与掩码系数结合起来,生成实例mask…

  • h5网站模板_超全超实用的80个模板网站,我全部整理在这里了「建议收藏」

    h5网站模板_超全超实用的80个模板网站,我全部整理在这里了「建议收藏」如果你喜欢本文章,欢迎关注,评论和转发,谢谢!模板网站,可谓是当代最受欢迎的网站类型之一,只要提供的足够新颖能够满足需求,必然成为懒癌青年们的最爱。这些网站深受喜爱的原因是:大家想要实现某种设计需求,但窘于自己技术没达到,时间来不及现学现卖等诸多因素,反正就是做不出来。正当你焦头烂耳临近崩溃的时候,别人告诉你有现成又好看的模板,想问又有谁能拒绝呢?当然,模板网站不一定全是免费的,都需要你付出一些东…

  • 优秀的程序员真的不写注释吗?

    优秀的程序员真的不写注释吗?我在很多地方看到这样一个观点,“请停止写注释,因为只有烂的代码才需要注释。”这个观点非常巧妙,它让我想起了孟子的一句话,“杨氏为我,是无君也;墨氏兼爱,是无父也。无父无君,是禽兽也。”动不动就骂别人是“禽兽”,我总觉得有点不妥,这很不符合孟子的浩然之气啊。有些大牛也有孟子这样的觉悟,如果有人要他给自己的代码加上注释,就好像是对他的一种侮辱:“我的代码写得这么优雅,你难道看不懂吗?注释是多余的!”我必须得承认,每个程序员都应该有一颗追求“优雅”的心,力争自己的代码更易阅读和理解——不只是针对机器,还有我

  • 这些Java的“武功秘籍”不是用来收藏的![通俗易懂]

    点击上方☝,轻松关注!及时获取有趣有料的技术文章在金庸的武侠世界里,有太多的武功绝学和武林秘籍,很多江湖人士为了得到一本武功秘籍而争的你死我亡,可以想象武功秘籍是多么的重要,获得一本失传的武功,并加以修炼,或许就可以称霸江湖,号令中原。(图片来源网络,见水印)在Java编程的世界中,也同样有很多“武功秘籍”,这些武功秘籍散落在不同的地方,很多出自大神之手!…

  • kworker_kiekert

    kworker_kiekert通过ps命令查看进程状态时,可以查看到kworker相关,大部分格式都是kworker/u2:0或者kworker/0:0H,查看资料得知:内核中有很多kworker,有绑定cpu的和不绑定cpu的,它支持cpu的hotplug时work的迁移。u:是unbound的缩写,代表没有绑定特定的CPU,kworker/u2:0中的2是work_pool的I…

  • genre-based_deepsort特征判断

    genre-based_deepsort特征判断  https://arxiv.org/abs/1804.01438https://blog.csdn.net/gavinmiaoc/article/details/80648754https://zhuanlan.zhihu.com/p/35296881 https://github.com/seathiefwang/MGN-pytorch

发表回复

您的电子邮箱地址不会被公开。

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