`

socket 客户端连接池实现

 
阅读更多

本文参考:http://cache.baidu.com/c?m=9f65cb4a8c8507ed4fece76310508a24420597634b86914323c3933fcf331d5c017be3b925251204d3c561640ab24859e1fa3c77341420c0c18ed714c9fecf6879877f67344f9141639244fe921163d620e14d99db0e96cce742e3b9a1d6c85523dd23016df1809c5b7003bb6ce76740f4d6ef5f635e07bb9d2715fe4e0123&p=8b2a9f1fce934eac59eace2c5f408c&newp=b46cc64adc9a02ff57ee9579420885231610db2151d0d74c3c&user=baidu&fm=sc&query=java+Socket+%BF%CD%BB%A7%B6%CB%C1%AC%BD%D3%B3%D8&qid=b594b3745708111f&p1=9

 

并对此文代码稍作修改,未经测试,只作参考。

 

自定义socket连接:

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import org.apache.log4j.Logger;

/**
 * <p>
 * Title: socket连接的简单实现
 * </p>
 * 
 * <p>
 * Description: 
 * </p>
 * 
 * <p>
 * Copyright: 融博技术有限公司 2012
 * </p>
 * 
 * @author 袁泉锋HO174959
 * @version 1.0
 * @date Oct 15, 2012
 *
 */
public class SocketConnection extends Socket {
	private static final Logger logger = Logger.getLogger("FrameLog");
	/**
	 * status false 繁忙 true 空闲
	 */
	private boolean status = true;

	/** 
	  *   默认的构造函数 
	  */
	public SocketConnection() {
		super();
	}

	/**
	 * ConnectionAdapter constructor
	 */
	public SocketConnection(String host, int port)
			throws UnknownHostException, IOException {
		super(host, port);
	}

	/**
	 * <Description>判断此连接是否空闲 
	 *
	 * @since Oct 15, 2012
	 * @return <Description>空闲返回ture,否则false 
	 *
	 */
	public boolean isFree() {
		return status;
	}

	/**
	 * <Description> 当使用此连接的时候设置状态为false(忙碌)
	 *
	 * @since Oct 15, 2012 <Description>
	 *
	 */
	public void setBusy() {
		this.status = false;
	}

	/**
	 * <Description>当客户端关闭连接的时候状态设置为true(空闲),放回连接池
	 *
	 * @since Oct 15, 2012 <Description>
	 *
	 */
	public void close() {
		logger.info("ConnectionAdapter Close : set   the   status   is   free");
		status = true;
	}
	
	/**
	 * <Description>销毁连接
	 * @throws IOException 
	 *
	 * @since Oct 15, 2012 <Description>
	 *
	 */
	public void destroy() throws IOException {
		//Close   socket   connection
		super.close();
		logger.info("ConnectionAdapter destroy!");
		// System.out.println( "Close   success   "   ); 
	}
}

 

 

连接池接口:

 

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * <p>
 * Title: 定义的抽象类,所有的子类必须单子模式去实现
 * </p>
 *    统一方法为public   ConnectionProvider   newInstance(); 
  *   连接提供器的抽象接口,每一个实现它的子类最好都是JAVABEAN, 
  *   这样它的方法就可以是被外界控制 
 * <p>
 * Description: 
 * </p>
 * 
 * <p>
 * Copyright: 融博技术有限公司 2012
 * </p>
 * 
 * @author 袁泉锋HO174959
 * @version 1.0
 * @date Oct 15, 2012
 *
 */
public interface SocketConnectionPoolInterface {
	public static final String SERVER_IP = "SERVER_IP_ADDRESS";
	public static final String SERVER_PORT = "SERVER_IP_PORT";
	public static final String MAX_SIZE = "MAX_SIZE";
	public static final String MIN_SIZE = "MIN_SIZE";
	/** 
	  *判断连接池内是否有连接 
	  *   @return   true   有连接返回true,否则返回false 
	  */
	public boolean isPooled();
	/** 
	  *   当此方法被调用的时候提供一个   socket 
	  *   @see   Socket 
	  *   @return   Socket   a   Connection   object. 
	  */
	public SocketConnection getConnection() throws java.net.SocketException;
	/** 
	  *   连接池初始化 
	  */
	public void init() throws UnknownHostException, IOException;
	/** 
	  *   连接池重新启动 
	  */
	public void restart() throws UnknownHostException, IOException;
	/** 
	  *   注销连接池 
	  */
	public void destroy();
}

 

连接池接口实现:

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Properties;

import org.apache.log4j.Logger;


/**
 * <p>
 * Title: 这是一个连接管理器的简单实现
 * </p>
 * 
 * <p>
 * Description: 
 * </p>
 * 
 * <p>
 * Copyright: 融博技术有限公司 2012
 * </p>
 * 
 * @author 袁泉锋HO174959
 * @version 1.0
 * @date Oct 15, 2012
 *
 */
public class SocketConnectionPool implements SocketConnectionPoolInterface {
	private static final Logger logger = Logger.getLogger("FrameLog");
	private Properties pro = null;
	private static SocketConnectionPoolInterface provider = null;
	private static Object object_lock = new Object();
	private String ip;
	private String port;
	/** 
	  *   默认的最大连接数 
	  */
	private int max_size = 20;
	/** 
	  *   默认的最小连接数 
	  */
	private int min_size = 10;
	/** 
	  *   Socket   connection池数组 
	  */
	private SocketConnection[] socketpool = null;
	/** 
	  *   构造对象的时候初始化连接池 
	  *   @throws   UnknownHostException   未知的主机异常 
	  *   @throws   IOException 
	  */
	private SocketConnectionPool(Properties pro) throws UnknownHostException,
			IOException {
		ip = pro.getProperty(SERVER_IP);
		port = pro.getProperty(SERVER_PORT);
		String max_size_s = pro.getProperty(MAX_SIZE);
		String min_size_s = pro.getProperty(MIN_SIZE);
		if (max_size_s != null) {
			max_size = Integer.parseInt(max_size_s);
		}
		if (min_size_s != null) {
			min_size = Integer.parseInt(min_size_s);
		}
		init(); //构造对象的时候初始化连接池 
	}

	/** 
	  *   判断是否已经池化 
	  *   @return   boolean   如果池化返回ture,反之返回false 
	  */
	public boolean isPooled() {
		if (socketpool != null) {
			return true;
		} else {
			return false;
		}
	}

	/** 
	  *返回一个连接 
	  *   @return   a   Connection   object. 
	  */
	public SocketConnection getConnection() {
		SocketConnection s = null;
		for (int i = 0; i < socketpool.length; i++) {
			if (socketpool[i] != null) {
				//如果有空闲的连接,返回一个空闲连接,如果没有,继续循环 
				if (socketpool[i].isFree()) {
					s = socketpool[i];
				} else {
					continue;
				}
			} else { //如果连接为空,证明小于最小连接数,重新生成连接 
				try {
					s = socketpool[i] = new SocketConnection(ip, Integer
							.parseInt(port));
				} catch (Exception e) {
					logger.error(e.getMessage());
					//never   throw 
				}
			}
		}
		/*//TODO 如果连接仍旧为空的话,则超过了最大连接数 
		if (s == null) {
			try { //生成普通连接,由客户端自行关闭,释放资源,不再由连接池管理 
				s = new Socket(ip, Integer.parseInt(port));
			} catch (Exception e) { //此异常永远不会抛出 
			}
		}*/
		//TODO 如果连接仍旧为空的话,等待一会继续获取
		while(s == null){
			try {
				Thread.sleep(1000);
				s = this.getConnection();
			} catch (InterruptedException e) {
				e.printStackTrace();
				logger.error(e.getMessage());
			}
		}
		s.setBusy();
		return s;
	}

	/** 
	  *   初始化连接池 
	  *   @throws   UnknownHostException   主机ip找不到 
	  *   @throws   IOException   此端口号上无server监听 
	  */
	public void init() throws UnknownHostException, IOException {
		socketpool = new SocketConnection[max_size];
		for (int i = 0; i < min_size; i++) {
			socketpool[i] = new SocketConnection(ip, Integer.parseInt(port));
			logger.info(" . ");
		}
		logger.info("socketPool   init   success!");
	}

	/** 
	  *   重新启动连接池 
	  *   @throws   UnknownHostException 
	  *   @throws   IOException 
	  */
	public void restart() throws UnknownHostException, IOException {
		destroy();
		init();
	}

	/** 
	  *   注销此连接池 
	  */
	public void destroy() {
		for (int i = 0; i < socketpool.length; i++) {
			if (socketpool[i] != null) {
				SocketConnection adapter = (SocketConnection) socketpool[i];
				try {
					adapter.destroy();
				} catch (IOException e) {
					logger.error(e.getMessage());
					e.printStackTrace();
				}
				logger.info(" . ");
				socketpool[i] = null;
			}
		}
		logger.info("SocketPool Destory   success!");
	}

	/** 
	  *   静态方法,生成此连接池实现的对象 
	  *   @param   pro   Properties   此连接池所需要的所有参数的封装 
	  *   @throws   UnknownHostException   主机无法找到 
	  *   @throws   IOException   与服务器无法建立连接 
	  *   @return   ConnectionProvider   返回父类ConnectionProvider 
	  */
	public static SocketConnectionPoolInterface newInstance(java.util.Properties pro)
			throws UnknownHostException, IOException {
		if (provider == null) {
			synchronized (object_lock) {
				if (provider == null) {
					provider = new SocketConnectionPool(pro);
				}
			}
		}
		return provider;
	}

	/** 
	  *设置系统属性   通过封装系统properties对象来封装所需要的不同值 
	  *   SERVER_IP,SERVER_PORT,MAX_SIZE,MIN_SIZE等父类定义的不同的参数 
	  *   @param   pro   Properties   传进来的系统属性 
	  */
	public void setProperties(Properties pro) {
		this.pro = pro;
	}
}

 

连接池管理器:

import java.lang.reflect.*;
import java.util.Properties;

import org.apache.log4j.Logger;

/**
 * <p>
 * Title: 连接管理器
 * </p>
 * 
 * <p>
 * Description: 
 * </p>
 * 
 * <p>
 * Copyright: 融博技术有限公司 2012
 * </p>
 * 
 * @author 袁泉锋HO174959
 * @version 1.0
 * @date Oct 15, 2012
 *
 */
public class SocketConnectionManager {
	private static final Logger logger = Logger.getLogger("FrameLog");
	//测试程序默认的连接池实现类 
	public static final String PROVIDER_CLASS = "com.rb.socketpool.MyConnectionProvider";
	//测试程序的默认ip 
	public static final String HOST = "127.0.0.1";
	//测试程序的默认端口号 
	public static final String PORT = "9880";
	/** 
	  *   注册钩子程序的静态匿名块,jvm退出的前一刻,调用ShutdownThread线程
	  */
	static {
		Runtime runtime = Runtime.getRuntime();
		Class c = runtime.getClass();
		try {
			Method m = c.getMethod("addShutdownHook",
					new Class[] { Thread.class });
			m.invoke(runtime, new Object[] { new ShutdownThread() });
		} catch (NoSuchMethodException e) {
			logger.error(e.getMessage());
			e.fillInStackTrace();
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
	}

	/** 
	  *   默认的构造函数 
	  */
	public SocketConnectionManager() {
	}

	/**
	 * <Description> 得到并初始化一个连接池 
	  *   连接池的实现类通过系统参数来传递进来,通过命令行-DConnectionProvider=YourImplClass 
	  *   如果没有指定的实现的话,则采用系统默认的实现类 
	  *   通过命令行传入的参数列表如下 
	  *   对方主机名-DHost=192.168.0.200 
	  *   对方端口号 -DPort=9880 
	  *   最小连接数     -DMax_size=10 
	  *   最大连结数 -DMin_size=20 
	  *   以上的值可以改变,但是参数不能改变, 
	  *   最大连结数和最小连接数可以省略,默认值分别为20和10 
	 *
	 * @since Oct 15, 2012
	 * @return
	 * @throws Exception <Description>
	 *
	 */
	public static SocketConnectionPoolInterface getConnectionProvider() throws Exception {
		String provider_class = System.getProperty("ConnectionProvider");
		if (provider_class == null){
			provider_class = PROVIDER_CLASS;
		}
		String host = System.getProperty("Host");
		if (host == null){
			host = HOST;
		}
		String port = System.getProperty("port");
		if (port == null){
			port = PORT;
		}
		String max_size = System.getProperty("Max_size");
		String min_size = System.getProperty("Min_size");

		Properties pro = new Properties();
		pro.setProperty(SocketConnectionPoolInterface.SERVER_IP, host);
		pro.setProperty(SocketConnectionPoolInterface.SERVER_PORT, port);
		if (max_size != null) {
			pro.setProperty(SocketConnectionPoolInterface.MAX_SIZE, max_size);
		}
		if (min_size != null) {
			pro.setProperty(SocketConnectionPoolInterface.MIN_SIZE, min_size);
		}
		//通过反射得到实现类 
		logger.info("Provider_class:" + provider_class);
		Class provider_impl = Class.forName(provider_class);
		//由于是单子模式,采用静态方法回调 
		Method m = provider_impl.getMethod("newInstance",
				new Class[] { java.util.Properties.class });
		SocketConnectionPoolInterface provider = null;
		try {
			provider = (SocketConnectionPoolInterface) m.invoke(provider_impl,
					new Object[] { pro });
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return provider;
	}

	/** 
	  * 
	  *   <p> 一个钩子的线程:   在程序结束的时候调用注销连接池 </p> 
	  *   <p> Description:   </p> 
	  *   <p> Copyright:   Copyright   Tarena(c)   2005 </p> 
	  *   <p> Company:   Tarena </p> 
	  *   @author   chengxing 
	  *   @version   1.0 
	  */
	private static class ShutdownThread extends Thread {
		public void run() {
			try {
				SocketConnectionPoolInterface provider = SocketConnectionManager
						.getConnectionProvider();
				if (provider != null) {
					provider.destroy();
				}
			} catch (Exception e) {
				logger.error(e.getMessage());
				e.printStackTrace();
			}
		}
	}

}

 

 

分享到:
评论

相关推荐

    java socket连接池 实现

    Java Socket 连接池实现是提高网络应用性能和效率的关键技术之一。在高并发的网络环境中,频繁地创建和销毁Socket连接会导致大量的系统资源浪费,影响整体性能。为了解决这个问题,开发人员通常会使用连接池来管理和...

    BIO Socket连接池

    `SocketServerPool`可能是一个服务器端的Socket连接池实现,它的主要职责包括: 1. 创建ServerSocket,监听特定端口,用于接收客户端的连接请求。 2. 当有新的客户端连接时,从连接池中取出一个Socket连接,与客户端...

    Socket连接池的简单应用

    为此,本文档介绍了一种解决这些问题的方法——Socket连接池技术,并通过具体实例来展示如何在客户端和服务端之间实现这一技术。 #### 二、Socket连接的基础概念 在深入探讨Socket连接池之前,我们需要了解两种...

    java socket连接池

    本文将深入探讨Java中的Socket连接池及其实现原理。 首先,理解Socket的基础知识至关重要。Socket是网络编程的基本接口,它提供了进程间通信(IPC)的能力,尤其是在互联网上不同主机间的通信。Java中的Socket类和...

    socket线程连接池实例

    本实例探讨的是如何利用Java中的Socket对象以及线程连接池技术,特别是`GenericObjectPool`来提高程序性能和效率。首先,我们需要理解Socket和线程连接池的基本概念。 **Socket**: Socket是网络通信的一种接口,它...

    Java实现Socket长连接和短连接

    长连接的实现可能涉及到线程池、连接池等技术,以及异常处理和超时策略。 **3. 实现原理** - **Java Socket API**:Java提供了Socket和ServerSocket类来创建和管理TCP连接。通过ServerSocket监听特定端口,等待...

    c#socket连接池和连接超时时间设置

    提供一个c# socket连接池设计的例子,解决socket并发连接限制的问题,并且提供一种设置连接超时时间的方法,默认连接超时时间是不能设置的,提供了socket网络发送数据的接口.可用于pos小票打印机通讯。

    Socket连接池的经典实例

    一个java socket连接池的典型实例 SocketClient,客户端测试类 SocketAdapter继承Socket类,重新封装socket类 SocketConnectionPool,连接池管理类 StartupSocketServer,socket服务器端的主线程,负责监听端口,当有...

    Socket多客户端连接

    描述中提到“可运行”,这意味着我们可能有一个示例代码或应用,它已经实现了多客户端连接的Socket服务器。通常,这样的程序会包含以下组件: 1. **服务器端**:创建一个监听Socket,绑定到特定IP和端口,然后调用`...

    socket服务端客户端源代码

    当有客户端连接时,`accept()`方法返回一个新的`Socket`对象,用于和该客户端的通信。 3. **数据交换**:服务端通过新建立的`Socket`对象的`InputStream`读取客户端发送的数据,并通过`OutputStream`向客户端发送...

    socket连接池加消息队列源码

    Socket连接池和消息队列是两种在分布式系统和网络编程中常见的技术,它们在提高系统性能、优化资源管理和实现异步通信方面起着至关重要的作用。在这个“socket连接池加消息队列源码”中,我们可以看到作者创建了一个...

    android客户端加服务端的socket长连接

    4. 服务端需要维护一个客户端连接池,处理多个客户端的并发连接。 二、客户端Socket设置 1. 创建Socket实例,指定服务器的IP地址和端口号。 2. 获取Socket的InputStream和OutputStream,用于读写数据。 3. 发送消息...

    Socket客户端和服务器端Demo

    本教程将深入讲解Socket客户端和服务器端的原理及实现。 一、Socket基础知识 1. Socket概念:Socket在英文中译为“插座”,在网络编程中,它代表一个网络连接的端点,是应用程序通过TCP/IP协议通信的入口。一个...

    socket客户端

    Socket客户端是网络编程中的一个重要概念,它主要用于实现应用程序与服务器之间的通信。在本文中,我们将深入探讨Socket客户端的原理、用途以及如何使用`commonlib`库来创建稳定的Socket客户端,同时也会涉及TCP协议...

    Android客户端socket.io官方Demo完整可运行版

    这可能涉及内存管理、连接池优化、消息队列设计等方面。 这个官方Demo可以帮助你快速上手,理解如何在Android应用中集成和使用Socket.IO。通过阅读代码、运行示例和调试,你将能够深入理解这些概念,并将它们应用到...

    java编写socket服务端和客户端给予cmpp3.0

    - 当有客户端连接时,创建一个新的 Socket 对象,为每个连接创建单独的线程处理,避免阻塞其他客户端的连接。 - 通过输入输出流解析接收到的 CMPP 消息,执行相应操作,如发送回执、存储消息等。 4. **客户端实现...

    Socket客户端和服务器通信例子,经过本人实测

    当客户端连接请求到达时,`accept()`方法将阻塞,直到有新的连接。一旦连接建立,`accept()`会返回一个新的`Socket`对象,用于与客户端进行数据交换。 在客户端(MainActivity),我们使用`java.net.Socket`类来...

    Socket聊天程序(一个服务端,多个客户端)

    4. 当客户端连接请求到达时,`Accept()`方法会返回一个新的Socket对象,用于与该客户端的通信。 5. 服务端可以使用`Receive()`和`Send()`方法接收和发送数据,与多个已连接的客户端进行并发通信。 客户端(Client)...

    Linux 线程池+连接池

    首先,线程池用于执行具体的业务逻辑,每个线程从连接池中获取已建立的连接,处理客户端的请求,完成后将连接放回池中。epoll负责监听所有连接的读写事件,当有新的连接请求或数据到达时,epoll_wait唤醒对应的线程...

Global site tag (gtag.js) - Google Analytics