




已阅读5页,还剩9页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
java实现的端口映射器下载源代码 作者:javafound 大小:152k 发布日期:2007-05-18 浏览:0 1.介绍:本文手把手的详解了jPortMap端口映射程序开发中的每一步,做为己运行在实际的企业项目中的应用, jPortMap程序较全面的展示了Thread、List、Vector、Socket、ServerSocket、Input/OutpuStream、File Read/Write、Properties等核心API的用法,是初学者快速进阶的一个优秀案例。在涉及内外网数据交换的网络应用系统开发中,我们经常需要做端口映射,比如放在外部网络主机上的程序要与内部网络上的某台机器建主TCP/IP连结,如下图(1)示: C机器可以与A机连通,但要与B机连通,由与不在同一网络,就无能为力了;这时,就需在A机器上做交换或是转发,来接通C与B之间的TCP/IP连结,即C机先与A机器建立Socket连结,A再与B机建立连结,然后由A在中间转发C与B通信的数据;B机器上可能运行着数据库,WebService等在Tcp/IP上通信的程序,而C机器必须访问这些服务。这里A机器就充当像现实生活中介绍人的角色,负责将C、B之间的通信数据流在Socket上转发;图1因此,A机需实现端口转发功能,在Liunx上,可以通过配置IPTable由OS实现,在本例中,我们将开发一个java实现的端口转发程序jPortMap,此程序将运行在A机器上,以实现转发C与B之间通信的转发。2.源码下载及测试说明:从www.NetJ上下载源代码解压后,可看到如下目录结构:现在,你可以修改一下jPortMap.cfg中的配置,比如,想通过本机的地址上的8899端口转发到56,则这样配置:#本地IPLocalIP.1 = #本地端口LocalPort.1 = 8899#目标IPDestHost.1 = 56 #目标端口DestPort.1 = 80#客户端IP过滤表,*表示许可模糊匹配AllowClient.1 = *.*.*.*,双击jPortMap.bat启动程序后,在你的IE里输入:8899试试看:)3.jPortMap程序类的构成说明:jPortMap由Main.java、Server.java、Transfer.java、Route.java、SysLog.java五个类构成。类文件功能概要:Main.java:程序启动主类,负责从配置文件读取转发的配置参数,启动转发服务器;Server.java:其实是一个ServerSocket服务器,接受C机器进入的Socket连结请求,生成Transfer.对象,由Transfer负责在本机(A上)转发B和C之间的通信。Route.java:转发对象的数据模板类,用来将转发配置映射为java对象,以由Server,ransfer对象使用。Transfer.java:按字面意思,可理解为“传送者”,如在图示中,当C要通过A连结B时,是先连结到A机上,这里在C和A间生成一个socket对象,Transfer对象则使用这个生成的socket对象和这个传输任务的Route对象执行具体的转发任务。SysLog.java:jPortMap是一个服务器端程序,在运行中可能会出现错误,因此需要一个日志工具,日志工具在jPortMap中只有一个对象存在,负责记录每天程序运行的信息,如错误,警行,一般信息等。配置文件:cfgjPortMap.cfg:这是一个文本文件,其中存放jPortMap的配置数据,当程序启动时,主类会从中读取数据配置程序,以生成多个Route对象在内存中保持数据。4.Route.java解析:我们己经说明,Route类是转发对象配置数据的模板类,当jPortMap启运时,它需要知道如下配置:1. 有多少处转发任务(意味着要监听哪几个ServerSocket);2. jPortMap程序对每个转发任务要启动的监听ServerSocket端口及所绑定的IP地址;3. 每个转发任务的目标IP地址和端口;因此,jPortMap一但启动,可能会创建多个Route对象,而每个具体的Route对象则保布着一个转发任务的以上配置数据。另外,从安全方面着想,我们的jPortMap程序还需要对请求进入的连结进行安全管理,这里我们简单的用IP过滤的方法,即jPortMap中ServerSocekt监听到的进入连结请求会认证IP地址,如发现IP地址没有在许可的列表中,则断开这个请求;所以Route类还要保存每个任务对应的许可IP表;我们的Route.java源文件如下: /* * Route.java * * Created on 2006年12月28日, 下午12:36 * * To change this template, choose Tools | Template Manager * and open the template in the editor. */package java.jportmap;/* *转发任务的配置数据对象模板 * Company: www.NetJ * author javafound */public class Route public Route() /jPortMap绑定的IP String LocalIP=; /监听的端口 int LocalPort=0; /转发数据的目标机器IP String DestHost=; /转发的目标端口 int DestPort=0; /这个转发上许可进入的IP列表 String AllowClient=; /重写的toString方法,输出具体Route对象的信息以便debug public String toString() StringBuffer stb = new StringBuffer(); stb.append( LocalADD + LocalIP); stb.append( : + LocalPort); stb.append( -DestHost + DestHost); stb.append( : + DestPort); stb.append( (AllowClient) + AllowClient); return stb.toString(); 可以比对cfgjPortMap.cfg(可用notepad打开)中的内容,Route类只需要据文本件中的配配生成多个Route对象或者说转发任务,再由其它对象来使用,因此,Route类的功能和结构很简单,就像映射表结构的javaBean一样,只是负责保存数据在内存中。5. SysLog.java解析:SysLog保存每天的日志信息到指定的目录下,简单的说就是提供方法供别的对象来调用,写内容到文件中:package java.jportmap;import java.io.*;import java.util.Calendar;/* * Title: 端口转发器 * Description:日志工具类 * Copyright: Copyright (c) 2005 * Company: www.NetJ * author javafound * version 1.0 */public class SysLog /记录输出一般信息 public static void info(String s) writeToTodayLog(INFO :, s); /记录警告信息 public static void warning(String s) writeToTodayLog(WARN:, s); /记录错误信息public static void severe(String s) writeToTodayLog(ERROR:, s); /输出到当天日志文件的具体实现 private static void writeToTodayLog(String flag, String msg) RandomAccessFile raf = null; try Calendar now = Calendar.getInstance(); String yyyy = String.valueOf(now.get(java.util.Calendar.YEAR); String mm = String.valueOf(now.get(Calendar.MONTH) + 1); String dd = String.valueOf(now.get(Calendar.DAY_OF_MONTH); String hh = String.valueOf(now.get(Calendar.HOUR_OF_DAY); String ff = String.valueOf(now.get(Calendar.MINUTE); String ss = String.valueOf(now.get(Calendar.SECOND); mm = (1 = mm.length() ? (0 + mm) : mm; dd = (1 = dd.length() ? (0 + dd) : dd; hh = (1 = hh.length() ? (0 + hh) : hh; ff = (1 = ff.length() ? (0 + ff) : ff; ss = (1 = ss.length() ? (0 + ss) : ss; String yyyymmdd = yyyy + mm + dd; String hhffss=hh+ff+ss; String path = System.getProperties().getProperty(user.dir) + File.separator + log; File p = new File(path); if (!p.exists() p.mkdirs(); path += File.separator + jPortMap_ + yyyymmdd + .log; File f = new File(path); if (f.isDirectory() f.delete(); raf = new RandomAccessFile(f, rw); raf.seek(raf.length(); raf.writeBytes(hhffss+ +flag + : + msg + rn); raf.close(); catch (Exception ex) System.out.println(write file has error= + ex); /* Creates a new instance of SysLog *做为一个工具类,一般不需要实例化,所以此处private */ private SysLog() 说明:首先我们看到提供的三个公用静态方法:/记录一般信息public static void info(String s) /记录警告信息public static void warning(String s)/记录错误信息public static void severe(String s) SysLog做为系统中的工具类,一般是不需要实例化的,所以只提供调用功能即可,这三个调用方法为其它对象提供了调用接口,分别输出不同类型的信息到目志中,而调用对象并不需要去关心具体日志的格式,日志文件命令,文件读写等问题-只需传入要记录的消息即可。System.getProperties()返回一个Properties对象,其实是一个Map接口的实现,其中存入格式为 名字:值 一一对应的表,系统的许多环境变量,如程序运行的当前目录user.dir,操作系统类型,java当前版本等都在其中存放。RandomAccessFile:在写日志时使用了这个类向日志文件中写入内容,其中seek(int length)可以指定跳过文件中内容的长度后再开始写入;这样我们的日志就不会丢失。6.Server.java解析:如其名,Server是一个转发服务器的实现类,我们的jPortMap可同时执行多个转发服务,所以每个Server对象都将做为一个独立的线程运行,在jPortMap.cfg中配置了几个转发任务,系统就会实例几个Route对象,并生成对应个数的的Server对象,每个Server对象使用自己的一个Route对象的数据在指定的端口启动监听服务,等待客户端(如前面图示则是C机器)发起的连结,接收到连结请求并通过IP验证后,这个Server对象则将具体的转发任务交给自己的一个Transfer对象去独立处理,而Server对象则继续运行,等待到来的连结请求。我们可以将这个Server理解为一个看门人的角色-使用ServerSocket监听指定端口,等待到来的连结,它只负责接待来客,并核查来客的身份,如核查通过,至于来客进的门怎么办,它不管-由它所持有的另外一个对象Transfer类的一个实例去处理。解析代码如下:package java.jportmap;import .*;import java.util.*;/* * Title: 端口转发器 * Description:启动监听服务 * Copyright: Copyright (c) 2005 * Company: www.NetJ * author javafound * version 1.0 */public class Server extends Thread /创建一个转发服务器 public Server(Route route, int id) this.route = route; connectionQueue = new Vector(); myID = id; start(); /关闭这个服务器: public void closeServer() isStop = true; if (null != myServer) closeServerSocket(); while (this.connectionQueue.size() 0) Transfer tc = (Transfer) connectionQueue.remove(0); tc.closeSocket(tc.socket); tc = null; /启动转发服务器的执行线程 public void run() SysL( start Transfer.: + route.toString(); ServerSocket myServer = null; try InetAddress myAD = Inet4Address.getByName(route.LocalIP); myServer = new ServerSocket(route.LocalPort, 4, myAD); catch (Exception ef) SysLog.severe(Create Server + route.toString() + error: + ef); closeServerSocket(); return; SysL(Transfer Server : + route.toString() + created OK); while (!isStop) String clientIP = ; try Socket sock = myServer.accept(); clientIP = sock.getInetAddress().getHostAddress(); if (checkIP(route, clientIP) SysLog.warning( ransfer Server : + route.toString() + Incoming: + sock.getInetAddress(); sock.setSoTimeout(0); connCounter+; Transfer myt = new Transfer(sock, route); connectionQueue.add(myt); else SysLog.warning( ransfer Server : + route.toString() + Refuse : + sock.getInetAddress(); closeSocket(sock); catch (Exception ef) SysLog.severe( Transfer Server : + route.toString() + accept error + ef); /检测进入的IP是否己许可 private static boolean checkIP(Route route, String inIP) String inI = string2StringArray(inIP, .); String list = string2StringArray(route.AllowClient, .); if (inI.length != list.length) SysLog.severe( Transfer Server Error Cfg AllowClient : + route.toString(); return false; for (int i = 0; i 0) os0.write(bytes, 0, ir); else if (ir 0) os1.write(bytes, 0, ir); / if (logging) writeLog(bytes,0,ir,false); else if (ir 0) Server ts = serverList.remove(0); ts.closeServer(); for (int i = 0; i 0) Server ts = serverList.remove(0); ts.closeServer(); /* *从配置文件读取数据,生成Route对象 * read cfg parameter * return boolean */ private static boolean loadCfgFile() try String userHome = System.getProperties().getProperty(user.dir); if (userHome = null) userHome = ; else userHome = userHome + File.separator; userHome += cfg + File.separator + jPortMap.cfg; InputStream is = new FileInputStream(userHome); Properties pt = new Properties(); pt.load(is); /共有几个业务模块 int ServiceCount = Integer.parseInt(pt.getProperty(TransferCount); for (; ServiceCount 0; ServiceCount-) Route r = new Route(); r.LocalIP = pt.getProperty(LocalIP. + ServiceCount).trim(); r.LocalPort = Integer.parseInt(pt.getProperty(LocalPort. + ServiceCount).trim(); r.DestHost = pt.getProperty(DestHost. + ServiceCount).trim(); r.DestPort = Integer.parseInt(pt.getProperty(DestPort. + ServiceCount).t
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年安徽省绿色农业氨水大宗采购与物流配送服务合同
- 2025年新型城镇化项目能源服务及节能技术实施合同
- 2025年老旧小区改造工程劳务分包合同
- 2025年绿色农业产业基地智能设备采购与系统集成合同
- 2025年度医疗设备制造厂技术支持团队人员服务合同
- 2025年KTV会员管理系统集成解决方案承包合作协议
- 2025年绿色建材玻璃制品模具研发与智能生产线建设合同
- 2025年电商平台商品质量检测与消费者权益保护协议
- 中药抗结膜炎作用机制-洞察及研究
- 2025年校园体育器材室个性化定制办公桌椅采购协议
- 人教版五年级数学上册第三单元小数除法教学设计(表格式)和单元测试题
- 2025年湖南省中考地理试题(解析版)
- 弱电工程维保合同
- 产后康复师培训课件
- 新加坡数学教学课件
- 宫颈癌术后的护理
- 数据中心设备进场计划及保证措施
- 儿童心理健康:焦虑症与抑郁症
- 肿瘤内科教学课件
- 2025年中国圆钢市场调查研究报告
- 石化公司门卫管理制度
评论
0/150
提交评论