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)


相关推荐

  • Traceroute原理「建议收藏」

    Traceroute原理「建议收藏」通过traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径。当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一样,但基本上来说大部分时候所走的路由是相同的。linux系统中,我们称之为traceroute,在MSWindows中为tracert。traceroute通过发送小的数据包到目的设备直到其返回,来测量其需要多长时间。一条路径上的每个设备traceroute要测3次。输出结果中包括每次测试的时间(ms)和

  • vue富文本编辑器插件推荐_vue富文本编辑器的使用

    vue富文本编辑器插件推荐_vue富文本编辑器的使用vue富文本编辑器,插件

    2022年10月14日
  • PHP smarty

    PHP smarty<?php/*一、什么是smarty?smarty是一个使用PHP写出来的模板PHP模板引擎,它提供了逻辑与外在内容的分离,简单的讲,目的就是要使用PHP程序员同美工分离,使用的程序员改变程序的

  • 应用程序正常初始化(0xc015002)失败解决方法

    应用程序正常初始化(0xc015002)失败解决方法

    2021年12月15日
  • SOAPAction是什么[通俗易懂]

    SOAPAction是什么[通俗易懂]SOAPAction是什么?最近在工作中遇到一个SOAPAction的问题,正好拿出来研究一把。  据说SOAPActionheader这玩意在SOAP1.1规范中着实让不少开发者喝了一壶。真的有这么难理解么?我想这应该是因为SOAP有两种非常不同的使用方式,而SOAPAction主要是被用来支持其中应用较少的一种方式的原因。在我看来,这种方式也非常有价值。  让我们先看看S…

  • 基于matlab的Canny算法的边缘检测(附源代码)

    基于matlab的Canny算法的边缘检测(附源代码)边缘概述边缘可以认为是图像中一定数量点亮度发生变化的地方,边缘检测大体上就是计算这个亮度变化的导数,依据导数的大小,判断亮度变化大小,从而界定目标与背景。在经典的边缘检测算法中Roberts算子,Prewitt算子,Sobel算子属于一阶差分算子,LoG算子,Canny算子属于二阶差分算子。一阶差分算子,就是求图像灰度变化曲线的导数,从而可以突出图像中的对象边缘,而二阶差分算子,求图像灰度变化导数的导数,对图像中灰度变化强烈的地方很敏感,从而可以突出图像的纹理结构。即一阶求边缘,二阶不仅检测出边缘还可检测

发表回复

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

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