网络编程:
按照网络拓扑结构可以分为:星型网络,环线网络,星形环线网络,总线网络,树形网络。
Osi/ISO:
OSI:开放系统服务,采用分层的结构化技术。将网络简化,模块化的设计网络。
分为七层:最高层为用户层,最底层为物理层。
应用层、表示层、会话层、传输层(TCP、UDP、SPX)、网络层(IP、IPX、RIP、OSPF)、数据链路层、物理层。
分层理由:由于结点之间联系很复杂,在制定协议时,把复杂成份分解成 一些简单的成份,再将它们复合起来。最常用的复合方式是层次方式,即同层间可以通信、上一层可以调用下一层,而与再下一层不发生关系。
TCP(Transmission Control Protocol)/IP模型:应用层、传输层、网络层、物理+数据链路层。TCP协议是一个面向连接的、可靠的协议。
UDP:UDP协议是一个不可靠的、无连接协议。
端口(port):可以进行网络通信的软件,数据进出的通道(0-65535,一般8000-20000,其他范围可能会绑定到服务上,产生冲突)
公认端口(Well Known Ports):从0到1023,它们紧密绑定(Binding)一些服务
注册端口(Registered Ports):从1024到49151。它们松散地绑定一些服务
动态和/或私有端口(Dynamic and/or Private Ports):从49152到65535。理论上,不应为服务分配这些端口
端口是一个程序或者服务的唯一标识。
网络编程:就是实现两台计算机之间的网络通信。
有关网络编程的类都是位于java.net包中。
InetAddress类:InetAddress类是用来描述网络中计算机的地址,一个InetAddress类就是一个网络地址。
类的作用 |
一个InetAddress类就是一个网络地址 |
构造方法 |
没有构造方法 |
创建对象 |
//1.创建InetAddress对象 //getLocaHost():获取InetAddress对象表示当前主机 InetAddress addr = InetAddress.getLocalHost(); //getByName(String IP):获取InetAddress对象表示指定的IP主机InetAddress addr = InetAddress.getByName("192.168.45.45"); |
常用方法 |
//2.常用的方法 //getHostName():获取当前InetAddress对象所代表的主机名称 String hostName = addr.getHostName(); //getHostAddress():获取InetAddress对象所代表的主机的IP String hostIP = addr.getHostAddress(); |
Socket类
Socket(套接):代表一个IP和port的组合,也就是两个程序的连接。
类的作用 |
用于向服务端发送请求,通过ip和port请求建立连接 |
构造方法 |
InetAddress addr = InetAddress.getByName("192.168.45.254"); Socket ss = new Socket("192.168.45.254", 8888); |
常用方法 |
InputStream is = ss.getInputStream(); OutputStream os = ss.getOutputStream(); socket.close(); |
ServerSocket类:用来描述网络服务。
类的作用 |
创建一个服务,等待客户连接 |
构造方法 |
//1.B程序创建一个服务,并占有一个端口号 ServerSocket server = new ServerSocket(8888); |
常用方法 |
//2.通过ServerSocket对象,调用accept()方法,让服务处于等待状态 Socket s = server.accept(); server.close(); |
UDP通信
DatagramSocket:用于接受和发送UDP数据,和Socket没有关系。
类的作用 |
一个DatagramSocket对象,即可以发送也可以接受数据报 |
构造方法 |
DatagramSocket() DatagramSocket(int port) |
创建对象 |
DatagramSocket ds = new DatagramSocket(2425); |
常用方法 |
ds.receive(DatagramPacket p); ds.send(DatagramPacket p); |
DatagramPacket:此类表示数据报包
类的作用 |
一个DatagramPacket对象表示一个数据包,可以用来封装UDP传输的数据 |
构造方法 |
DatagramPacket(byte[] buf, int length) DatagramPacket(byte[] buf, int length, InetAddress address, int port); |
创建对象 |
DatagramPacket p = new DatagramPacket(bs,bs.length,addr,8899); |
常用方法 |
p.getAddress(); p.getData(); get.Length(); p.getPort(); |
URL:统一资源定位器,表示Internet上某一个资源地址。
类的作用 |
一个URL对象就表示一个网络中的资源文件 |
构造方法 |
URL(String spec) URL(String protocol, String host, int port, String file) |
创建对象 |
URL u = new URL("http://192.168.45.66:80/sims/bbb/a.jpg"); |
常用方法 |
u. openConnection(); |
连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用。
好处
连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用。
这种把连接“汇集”起来的技术基于这样的一个事实:对于大多数应用程序,当它们正在处理通常需要数毫秒完成的事务时,仅需要能够访问JDBC 连接的 1 个线程。当不处理事务时,这个连接就会闲置。相反,连接池允许闲置的连接被其它需要的线程使用。
事实上,当一个线程需要用 JDBC 对一个 GBase 或其它数据库操作时,它从池中请求一个连接。当这个线程使用完了这个连接,将它返回到连接池中,这样这就可以被其它想使用它的线程使用。
当连接从池中“借出”,它被请求它的线程专有地使用。从编程的角度来看,这和用户的线程每当需要一个 JDBC 连接的时候调用DriverManager.getConnection() 是一样的,采用连接池技术,可通过使用新的或已有的连接结束线程。
连接池可以极大的改善用户的 Java 应用程序的性能,同时减少全部资源的使用。连接池主要的优点有:
减少连接创建时间
虽然与其它数据库相比 GBase 提供了较为快速连接功能,但是创建新的 JDBC 连接仍会招致网络和 JDBC 驱动的开销。如果这类连接是“循环”使用的,使用该方式这些花销就可避免。
简化的编程模式
当使用连接池时,每一个单独的线程能够像创建了一个自己的 JDBC 连接一样操作,允许用户直接使用JDBC编程技术。
受控的资源使用
如果用户不使用连接池,而是每当线程需要时创建一个新的连接,那么用户的应用程序的资源使用会产生非常大的浪费并且可能会导致高负载下的异常发生。
注意,每个连到 GBase 的连接在客户端和服务器端都有花销(内存,CPU,上下文切换等等)。每个连接均会对应用程序和 GBase 服务器的可用资源带来一定的限制。不管这些连接是否在做有用的工作,仍将使用这些资源中的相当一部分。
连接池能够使性能最大化,同时还能将资源利用控制在一定的水平之下,如果超过该水平,应用程序将崩溃而不仅仅是变慢。
2运作原理
在实际应用开发中,特别是在WEB应用系统中,如果JSP、Servlet或EJB使用JDBC直接访问数据库中的数据,每一次数据访问请求都必须经历建立数据库连接、打开数据库、存取数据和关闭数据库连接等步骤,而连接并打开数据库是一件既消耗资源又费时的工作,如果频繁发生这种数据库操作,系统的性能必然会急剧下降,甚至会导致系统崩溃。数据库连接池技术是解决这个问题最常用的方法,在许多应用程序服务器(例如:Weblogic,WebSphere,JBoss)中,基本都提供了这项技术,无需自己编程,但是,深入了解这项技术是非常必要的。
数据库连接池技术的思想非常简单,将数据库连接作为对象存储在一个Vector对象中,一旦数据库连接建立后,不同的数据库访问请求就可以共享这些连接,这样,通过复用这些已经建立的数据库连接,可以克服上述缺点,极大地节省系统资源和时间。
数据库连接池的主要操作如下:
(1)建立数据库连接池对象(服务器启动)。
(2)按照事先指定的参数创建初始数量的数据库连接(即:空闲连接数)。
(3)对于一个数据库访问请求,直接从连接池中得到一个连接。如果数据库连接池对象中没有空闲的连接,且连接数没有达到最大(即:最大活跃连接数),创建一个新的数据库连接。
(4)存取数据库。
(5)关闭数据库,释放所有数据库连接(此时的关闭数据库连接,并非真正关闭,而是将其放入空闲队列中。如实际空闲连接数大于初始空闲连接数则释放连接)。
(6)释放数据库连接池对象(服务器停止、维护期间,释放数据库连接池对象,并释放所有连接)。
连接池管理类是连接池类的外覆类(wrapper),符合单例模式,即系统中只能有一个连接池管理类的实例。其主要用于对多个连接池对象的管理,具有以下功能:①装载并注册特定数据库的JDBC驱动程序;②根据属性文件给定的信息,创建连接池对象;③为方便管理多个连接池对象,为每一个连接池对象取一个名字,实现连接池名字与其实例之间的映射;④跟踪客户使用连接情况,以便需要时关闭连接释放资源。连接池管理类的引入主要是为了方便对多个连接池的使用和管理,如系统需要连接不同的数据库,或连接相同的数据库但由于安全性问题,需要不同的用户使用不同的名称和密码。
2、连接池实现
下面给出连接池类和连接池管理类的主要属性及所要实现的基本接口:
public class DBConnectionPool implements TimerListener{
private int checkedOut;//已被分配出去的连接数
private ArrayList freeConnections = new ArrayList();//容器,空闲池,根据//创建时间顺序存放已创建但尚未分配出去的连接
private int minConn;//连接池里连接的最小数量
private int maxConn;//连接池里允许存在的最大连接数
private String name;//为这个连接池取个名字,方便管理
private String password;//连接数据库时需要的密码
private String url;//所要创建连接的数据库的地址
private String user;//连接数据库时需要的用户名
public Timer timer;//定时器
public DBConnectionPool(String name, String URL, String user, String
password, int maxConn)//公开的构造函数
public synchronized void freeConnection(Connection con) //使用完毕之后,//把连接返还给空闲池
public synchronized Connection getConnection(long timeout)//得到一个连接,//timeout是等待时间
public synchronized void release()//断开所有连接,释放占用的系统资源
private Connection newConnection()//新建一个数据库连接
public synchronized void TimerEvent() //定时器事件处理函数
}
public class DBConnectionManager {
static private DBConnectionManager instance;//连接池管理类的唯一实例
static private int clients;//客户数量
private ArrayList drivers = new ArrayList();//容器,存放数据库驱动程序
private HashMap pools = new HashMap ();//以name/value的形式存取连接池//对象的名字及连接池对象
static synchronized public DBConnectionManager getInstance()//如果唯一的//实例instance已经创建,直接返回这个实例;否则,调用私有构造函数,创//建连接池管理类的唯一实例
private DBConnectionManager()//私有构造函数,在其中调用初始化函数init()
public void freeConnection(String name, Connection con)// 释放一个连接,//name是一个连接池对象的名字
public Connection getConnection(Stringname)//从名字为name的连接池对象//中得到一个连接
public Connection getConnection(Stringname, long time)//从名字为name
//的连接池对象中取得一个连接,time是等待时间
public synchronized void release()//释放所有资源
private void createPools(Properties props)//根据属性文件提供的信息,创建//一个或多个连接池
private void init()//初始化连接池管理类的唯一实例,由私有构造函数调用
private void loadDrivers(Properties props)//装载数据库驱动程序
}
3、连接池使用
上面所实现的连接池在程序开发时如何应用到系统中呢?下面以Servlet为例说明连接池的使用。
Servlet的生命周期是:在开始建立servlet时,调用其初始化(init)方法。之后每个用户请求都导致一个调用前面建立的实例的service方法的线程。最后,当服务器决定卸载一个servlet时,它首先调用该servlet的 destroy方法。
根据servlet的特点,我们可以在初始化函数中生成连接池管理类的唯一实例(其中包括创建一个或多个连接池)。如:
public void init() throws ServletException
{
connMgr = DBConnectionManager.getInstance();
}
然后就可以在service方法中通过连接池名称使用连接池,执行数据库操作。最后在destroy方法中释放占用的系统资源,如:
public void destroy() {
connMgr.release(); super.destroy();
}
conn = list.removeLast();// 不要get拿,get不是真的拿走,而是指向,不能锁定
开源连接池: