版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、下載源代碼 1.介紹: 本文手把手的詳解了jPortMap端口映射程序開發(fā)中的每一步,做為己運(yùn)行在實(shí)際的企業(yè)項(xiàng)目中的應(yīng)用, jPortMap程序較全面的展示了Thread、List、Vector、Socket、ServerSocket、Input/OutpuStream、File Read/Write、Properties等核心API的用法,是初學(xué)者快速進(jìn)階的一個(gè)優(yōu)秀案例。 在涉及內(nèi)外網(wǎng)數(shù)據(jù)交換的網(wǎng)絡(luò)應(yīng)用系統(tǒng)開發(fā)中,我們經(jīng)常需要做端口映射,比如
2、放在外部網(wǎng)絡(luò)主機(jī)上的程序要與內(nèi)部網(wǎng)絡(luò)上的某臺機(jī)器建主TCP/IP連結(jié),如下圖(1)示: C機(jī)器可以與A機(jī)連通,但要與B機(jī)連通,由與不在同一網(wǎng)絡(luò),就無能為力了;這時(shí),就需在A機(jī)器上做交換或是轉(zhuǎn)發(fā),來接通C與B之間的TCP/IP連結(jié),即C機(jī)先與A機(jī)器建立Socket連結(jié),A再與B機(jī)建立連結(jié),然后由A在中間轉(zhuǎn)發(fā)C與B通信的數(shù)據(jù);B機(jī)器上可能運(yùn)行著數(shù)據(jù)庫,WebService等在Tcp/IP上通信的程序,而C機(jī)器必須訪問這些服務(wù)。這里A機(jī)器就充當(dāng)像現(xiàn)實(shí)生活中介紹人的角色,負(fù)責(zé)將C、B之間的通信數(shù)據(jù)流在Socket上轉(zhuǎn)發(fā);圖1
3、60; 因此,A機(jī)需實(shí)現(xiàn)端口轉(zhuǎn)發(fā)功能,在Liunx上,可以通過配置IPTable由OS實(shí)現(xiàn),在本例中,我們將開發(fā)一個(gè)java實(shí)現(xiàn)的端口轉(zhuǎn)發(fā)程序jPortMap,此程序?qū)⑦\(yùn)行在A機(jī)器上,以實(shí)現(xiàn)轉(zhuǎn)發(fā)C與B之間通信的轉(zhuǎn)發(fā)。2.源碼下載及測試說明:從www.NetJ上下載源代碼解壓后,可看到如下目錄結(jié)構(gòu): 現(xiàn)在,你可以修改一下jPortMap.cfg中的配置,比如,想通過本機(jī)的地址上的8899端口轉(zhuǎn)發(fā)到56,則這樣配置:#本地IPLocalIP.1 = #本地端口LocalPort.1 = 8
4、899#目標(biāo)IPDestHost.1 = 56 #目標(biāo)端口DestPort.1 = 80#客戶端IP過濾表,*表示許可模糊匹配AllowClient.1 = *.*.*.*,雙擊jPortMap.bat啟動(dòng)程序后,在你的IE里輸入:8899試試看:)3.jPortMap程序類的構(gòu)成說明:jPortMap由Main.java、Server.java、Transfer.java、Route.java、SysLog.java五個(gè)類構(gòu)成。類文件功能概要:Main.java:程序啟動(dòng)主類,負(fù)責(zé)從配置文件讀取轉(zhuǎn)發(fā)的配置參數(shù),啟動(dòng)轉(zhuǎn)發(fā)服務(wù)器;Server.ja
5、va:其實(shí)是一個(gè)ServerSocket服務(wù)器,接受C機(jī)器進(jìn)入的Socket連結(jié)請求,生成Transfer.對象,由Transfer負(fù)責(zé)在本機(jī)(A上)轉(zhuǎn)發(fā)B和C之間的通信。Route.java:轉(zhuǎn)發(fā)對象的數(shù)據(jù)模板類,用來將轉(zhuǎn)發(fā)配置映射為java對象,以由Server,ransfer對象使用。Transfer.java:按字面意思,可理解為“傳送者”,如在圖示中,當(dāng)C要通過A連結(jié)B時(shí),是先連結(jié)到A機(jī)上,這里在C和A間生成一個(gè)socket對象,Transfer對象則使用這個(gè)生成的socket對象和這個(gè)傳輸任務(wù)的Route對象執(zhí)行具體的轉(zhuǎn)發(fā)任務(wù)。SysLog.java:jPortMap是一個(gè)服務(wù)器端
6、程序,在運(yùn)行中可能會(huì)出現(xiàn)錯(cuò)誤,因此需要一個(gè)日志工具,日志工具在jPortMap中只有一個(gè)對象存在,負(fù)責(zé)記錄每天程序運(yùn)行的信息,如錯(cuò)誤,警行,一般信息等。配置文件: cfgjPortMap.cfg:這是一個(gè)文本文件,其中存放jPortMap的配置數(shù)據(jù),當(dāng)程序啟動(dòng)時(shí),主類會(huì)從中讀取數(shù)據(jù)配置程序,以生成多個(gè)Route對象在內(nèi)存中保持?jǐn)?shù)據(jù)。4.Route.java解析:我們己經(jīng)說明,Route類是轉(zhuǎn)發(fā)對象配置數(shù)據(jù)的模板類,當(dāng)jPortMap啟運(yùn)時(shí),它需要知道如下配置:1. 有多少處轉(zhuǎn)發(fā)任務(wù)(意味著要監(jiān)聽哪幾個(gè)ServerSocket);2. jPortMap程序?qū)γ總€(gè)
7、轉(zhuǎn)發(fā)任務(wù)要啟動(dòng)的監(jiān)聽ServerSocket端口及所綁定的IP地址;3. 每個(gè)轉(zhuǎn)發(fā)任務(wù)的目標(biāo)IP地址和端口; 因此,jPortMap一但啟動(dòng),可能會(huì)創(chuàng)建多個(gè)Route對象,而每個(gè)具體的Route對象則保布著一個(gè)轉(zhuǎn)發(fā)任務(wù)的以上配置數(shù)據(jù)。另外,從安全方面著想,我們的jPortMap程序還需要對請求進(jìn)入的連結(jié)進(jìn)行安全管理,這里我們簡單的用IP過濾的方法,即jPortMap中ServerSocekt監(jiān)聽到的進(jìn)入連結(jié)請求會(huì)認(rèn)證IP地址,如發(fā)現(xiàn)IP地址沒有在許可的列表中,則斷開這個(gè)請求;所以Route類還要保存每個(gè)任務(wù)對應(yīng)的許可IP表;我們的Route.java源文件如下
8、: /* * 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;/* *轉(zhuǎn)發(fā)任務(wù)的配置數(shù)據(jù)對象模板 * * author javafound */public class Route public Route() /jPortMap綁定的IP String LocalIP="" /監(jiān)聽的
9、端口 int LocalPort=0; /轉(zhuǎn)發(fā)數(shù)據(jù)的目標(biāo)機(jī)器IP String DestHost="" /轉(zhuǎn)發(fā)的目標(biāo)端口 int DestPort=0; /這個(gè)轉(zhuǎn)發(fā)上許可進(jìn)入的IP列表 String AllowClient="" /重寫的toString方法,輸出具體Route對象的信息以便debug public String toString() StringBuffer stb = new StringBuffer(); stb.append(" LocalADD " + LocalIP); stb.append("
10、:" + LocalPort); stb.append(" ->DestHost " + DestHost); stb.append(" :" + DestPort); stb.append(" (AllowClient) " + AllowClient); return stb.toString(); 可以比對cfgjPortMap.cfg(可用notepad打開)中的內(nèi)容,Route類只需要據(jù)文本件中的配配生成多個(gè)Route對象或者說轉(zhuǎn)發(fā)任務(wù),再由其它對象
11、來使用,因此,Route類的功能和結(jié)構(gòu)很簡單,就像映射表結(jié)構(gòu)的javaBean一樣,只是負(fù)責(zé)保存數(shù)據(jù)在內(nèi)存中。5. SysLog.java解析:SysLog保存每天的日志信息到指定的目錄下,簡單的說就是提供方法供別的對象來調(diào)用,寫內(nèi)容到文件中:package java.jportmap;import java.io.*;import java.util.Calendar;/* * Title: 端口轉(zhuǎn)發(fā)器 * Description:日志工具類 * Copyright: Copyright (c) 2005 * author javafound * version 1.0 */public c
12、lass SysLog /記錄輸出一般信息 public static void info(String s) writeToTodayLog("INFO :", s); /記錄警告信息 public static void warning(String s) writeToTodayLog("WARN:", s); /記錄錯(cuò)誤信息public static void severe(String s) writeToTodayLog("ERROR:", s); /輸出到當(dāng)天日志文件的具體實(shí)現(xiàn) private static void w
13、riteToTodayLog(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
14、 = 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
15、) : 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); i
16、f (!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 + &q
17、uot;rn"); raf.close(); catch (Exception ex) System.out.println("write file has error=" + ex); /* Creates a new instance of SysLog *做為一個(gè)工具類,一般不需要實(shí)例化,所以此處private */ private SysLog() 說明:首先我們看到提供的三個(gè)公用靜態(tài)方法:/記錄一般信息public static void info(String s) /記錄警告信息public static void warning(String s)
18、/記錄錯(cuò)誤信息public static void severe(String s) SysLog做為系統(tǒng)中的工具類,一般是不需要實(shí)例化的,所以只提供調(diào)用功能即可,這三個(gè)調(diào)用方法為其它對象提供了調(diào)用接口,分別輸出不同類型的信息到目志中,而調(diào)用對象并不需要去關(guān)心具體日志的格式,日志文件命令,文件讀寫等問題-只需傳入要記錄的消息即可。 System.getProperties()返回一個(gè)Properties對象,其實(shí)是一個(gè)Map接口的實(shí)現(xiàn),其中存入格式為 名字:值 一一對應(yīng)的表,系統(tǒng)的許多環(huán)境變量,如程
19、序運(yùn)行的當(dāng)前目錄user.dir,操作系統(tǒng)類型,java當(dāng)前版本等都在其中存放。 RandomAccessFile:在寫日志時(shí)使用了這個(gè)類向日志文件中寫入內(nèi)容,其中seek(int length)可以指定跳過文件中內(nèi)容的長度后再開始寫入;這樣我們的日志就不會(huì)丟失。6.Server.java解析: 如其名,Server是一個(gè)轉(zhuǎn)發(fā)服務(wù)器的實(shí)現(xiàn)類,我們的jPortMap可同時(shí)執(zhí)行多個(gè)轉(zhuǎn)發(fā)服務(wù),所以每個(gè)Server對象都將做為一個(gè)獨(dú)立的線程運(yùn)行,在jPortMap.cfg中配置了幾個(gè)轉(zhuǎn)發(fā)任務(wù),系統(tǒng)就
20、會(huì)實(shí)例幾個(gè)Route對象,并生成對應(yīng)個(gè)數(shù)的的Server對象,每個(gè)Server對象使用自己的一個(gè)Route對象的數(shù)據(jù)在指定的端口啟動(dòng)監(jiān)聽服務(wù),等待客戶端(如前面圖示則是C機(jī)器)發(fā)起的連結(jié),接收到連結(jié)請求并通過IP驗(yàn)證后,這個(gè)Server對象則將具體的轉(zhuǎn)發(fā)任務(wù)交給自己的一個(gè)Transfer對象去獨(dú)立處理,而Server對象則繼續(xù)運(yùn)行,等待到來的連結(jié)請求。 我們可以將這個(gè)Server理解為一個(gè)看門人的角色-使用ServerSocket監(jiān)聽指定端口,等待到來的連結(jié),它只負(fù)責(zé)接待來客,并核查來客的身份,如核查通過,至于來客進(jìn)的門怎么辦,它不管-
21、由它所持有的另外一個(gè)對象Transfer類的一個(gè)實(shí)例去處理。解析代碼如下:package java.jportmap;import .*;import java.util.*;/* * Title: 端口轉(zhuǎn)發(fā)器 * Description:啟動(dòng)監(jiān)聽服務(wù) * Copyright: Copyright (c) 2005 * author javafound * version 1.0 */public class Server extends Thread /創(chuàng)建一個(gè)轉(zhuǎn)發(fā)服務(wù)器 public Server(Route route, int id) this.route = route; conne
22、ctionQueue = new Vector(); myID = id; start(); /關(guān)閉這個(gè)服務(wù)器: 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; /啟動(dòng)轉(zhuǎn)發(fā)服務(wù)器的執(zhí)行線程 public void
23、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() + &q
24、uot; 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, cl
25、ientIP) 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() + &
26、quot; Refuse :" + sock.getInetAddress(); closeSocket(sock); catch (Exception ef) SysLog.severe(" Transfer Server : " + route.toString() + " accept error" + ef); /檢測進(jìn)入的IP是否己許可 private static boolean checkIP(Route route, String inIP) String inI = string2StringArray(inIP, "
27、;."); 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 < inI.length; i+) if (!inIi.equals(listi) && !(listi.equals
28、("*") System.out.println(": " + inIi + " :" + listi); return false; return true; /* * param srcString 原字符串 * param separator 分隔符 * return 目的數(shù)組 */ private static final String string2StringArray(String srcString, String separator) int index = 0; String temp; StringTokeniz
29、er st = new StringTokenizer(srcString, separator); temp = new Stringst.countTokens(); while (st.hasMoreTokens() tempindex = st.nextToken().trim(); index+; return temp; /關(guān)閉ServerSocket private void closeServerSocket() try this.myServer.close(); catch (Exception ef) private void closeSocket(Socket s)
30、try s.close(); catch (Exception ef) /服務(wù)器 private ServerSocket myServer = null; /連結(jié)隊(duì)列控制 private boolean isStop = false; / private Vector connectionQueue = null; private int connCounter = 0; / 路由對象 private Route route = null; /連結(jié)的ID號,暫未用 private static int myID = 0; Server類關(guān)鍵功能是在一個(gè)獨(dú)立的線程中執(zhí)行監(jiān)
31、聽任務(wù),當(dāng)我們實(shí)例化一個(gè)ServerSocket時(shí),即綁定了本機(jī)的一個(gè)IP和端口,這個(gè)ServerSocket對象就在這個(gè)地址(由IP和端口組成)上通過調(diào)用accept()方法等待客戶端連結(jié),默認(rèn)情況下,這個(gè)等待會(huì)一直持續(xù),直到有一個(gè)連結(jié)進(jìn)入-生成一個(gè)socket對象;而我們的ServerSocket.accept()是在一個(gè)wilhe循環(huán)中,這保證了監(jiān)聽服務(wù)器不會(huì)中途退出。7. Transfer.java解析 在分析Server.java中我們看到,Server做為一個(gè)服務(wù)器,在與客戶端建立連結(jié)后使用生成的Socket對象和自己的Ro
32、utc對象來實(shí)例化一個(gè)Transfer,具體的傳輸工作就交給了Transfer對象完成。 Server生成的Socket對象是機(jī)器C與A之間連結(jié)的一個(gè)代碼,通過這個(gè)Socekt對象上的Input/OutPut Stream,可以讓C與A之間通信-工作還只完成了一半,這里我們還需要建立A與B之間的Socket連結(jié),這里就出現(xiàn)了兩個(gè)Socket連結(jié),分別是C與A間,我們叫SocketCA;A與B間我們假設(shè)叫做SocketAB; Transfer對象的任務(wù)就是行建立SocketAB,然后,將SocketCA的輸入寫入到SocketAB的輸出流,將SocketAB的輸
33、出流寫到SocketCA的輸出流中,這樣,就完成了C,B機(jī)器之間的數(shù)據(jù)轉(zhuǎn)發(fā)。package java.jportmap;import .*;import java.io.*;/* * Title: 端口轉(zhuǎn)發(fā)器 * Description: 對連結(jié)進(jìn)行轉(zhuǎn)發(fā)處理 * Copyright: Copyright (c) 2005 * author javafound * version 1.0 */public class Transfer extends Thread /* * 創(chuàng)建傳輸對象 * param s Socket :進(jìn)入的socket * param route Route:轉(zhuǎn)發(fā)配置 *
34、/ public Transfer(Socket s, Route route) this.route = route; this.socket = s; this.start(); / 執(zhí)行操作的線程 public void run() Socket outbound = null; try outbound = new Socket(route.DestHost, route.DestPort); socket.setSoTimeout(TIMEOUT); InputStream is = socket.getInputStream(); outbound.setSoTimeout(TIM
35、EOUT); OutputStream os = outbound.getOutputStream(); pipe(is, outbound.getInputStream(), os, socket.getOutputStream(); catch (Exception e) SysLog.severe(" transfer error:" +route.toString()+ " :" + e); finally SysLog.warning("Disconnect :"+ route.toString(); closeSocket
36、(outbound); closeSocket(socket); /* *傳輸?shù)膶?shí)現(xiàn)方法 */ private void pipe(InputStream is0, InputStream is1, OutputStream os0, OutputStream os1) try int ir; byte bytes = new byteBUFSIZ; while (true) try if (ir = is0.read(bytes) > 0) os0.write(bytes, 0, ir); else if (ir < 0) break; catch (InterruptedIOE
37、xception e) try if (ir = is1.read(bytes) > 0) os1.write(bytes, 0, ir); / if (logging) writeLog(bytes,0,ir,false); else if (ir < 0) break; catch (InterruptedIOException e) catch (Exception e0) SysLog.warning(" Method pipe" + this.route.toString() + " error:" + e0); /關(guān)閉socket
38、 void closeSocket(Socket s) try s.close(); catch (Exception ef) /傳輸任務(wù)的Route對象Route route = null; / 傳入數(shù)據(jù)用的SocketSocket socket; /超時(shí) static private int TIMEOUT = 1000; /緩存 static private int BUFSIZ = 1024;8.Main.java解析OK,至此己萬事具備!我們需要一個(gè)啟動(dòng)主類,根據(jù)讀入的配置文件數(shù)據(jù)來啟動(dòng)轉(zhuǎn)發(fā)服務(wù)器,執(zhí)行轉(zhuǎn)發(fā)工作:package java.jportmap;import java.io
39、.*;import java.util.*;import .*;/* * Title: 端口轉(zhuǎn)發(fā)器 * Description:啟動(dòng)主類:讀取配置,啟動(dòng)監(jiān)聽服務(wù) * Copyright: Copyright (c) 2005 * author javafound * version 1.0 */public class Main /start. public static void main(String args) startService(); /start public static void startService() if (!loadCfgFile() System.exit(1
40、); while (serverList.size() > 0) Server ts = serverList.remove(0); ts.closeServer(); for (int i = 0; i < routeList.size(); i+) Route r = routeList.get(i); Server server = new Server(r, i); serverList.add(server); / 停止服務(wù)接口,備用其它模塊調(diào)用 public static void stop() while (serverList.size() > 0) Serv
41、er ts = serverList.remove(0); ts.closeServer(); /* *從配置文件讀取數(shù)據(jù),生成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
42、+ File.separator; userHome += "cfg" + File.separator + "jPortMap.cfg" InputStream is = new FileInputStream(userHome); Properties pt = new Properties(); pt.load(is); /共有幾個(gè)業(yè)務(wù)模塊 int ServiceCount = Integer.parseInt(pt.getProperty("TransferCount"); for (; ServiceCount > 0
43、; 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.
44、parseInt(pt.getProperty("DestPort." + ServiceCount).trim(); r.AllowClient = pt.getProperty("AllowClient." + ServiceCount). trim(); routeList.add(r); is.close(); SysL("ystem Read cfg file OK"); catch (Exception e) System.out.println("找不到配置文件:"+e); SysLog
45、.severe("loadCfgFile false :" + e); return false; return true; /Server服務(wù)器集合 private static List< Server> serverList = new ArrayList(); /Route集合 private static List< Route> routeList = new ArrayList(); Main類中需要注意的是loadCfgFile()方法,它用來讀取當(dāng)前目錄下面cfg/jPortMap.c
46、fg文件中的配置數(shù)據(jù),如讀取成功,返加ture值,如讀取失敗,程序測會(huì)退出。另外:/Server服務(wù)器集合private static List<Server> serverList = new ArrayList();/Route集合private static List<Route> routeList = new ArrayList();這兩行代碼,生成兩個(gè)列表,來保存己啟動(dòng)的Server對象和Route對象。 現(xiàn)在,我們只要啟動(dòng)Main類,jPortMap就開始運(yùn)行了,同時(shí)會(huì)在log目錄下行成每天的運(yùn)行日志;當(dāng)然,千
47、萬不要忘了cfg/目錄下面jPortMap.cfg中配置轉(zhuǎn)發(fā)的參數(shù),配置的具體說明在該文件中有注解。源碼目錄結(jié)構(gòu)圖(NetBean中):9.改進(jìn)設(shè)想: 無論如何,這還是個(gè)比較簡陋的程序!假如我們把配置改成XML格式、假如我們使用Thread Pool來執(zhí)行任務(wù)、假如我們使用NIO、假如我們再做一套PL的UI界面.,您的任何建議,都會(huì)是對jPortMap走向完美的支持,請登陸www.NetJ發(fā)表您的看法,發(fā)布您的創(chuàng)新!當(dāng)然,www.NetJ現(xiàn)在己增加了許多新東東讓您欣賞!下載源代碼 1.介紹:
48、; 本文手把手的詳解了jPortMap端口映射程序開發(fā)中的每一步,做為己運(yùn)行在實(shí)際的企業(yè)項(xiàng)目中的應(yīng)用, jPortMap程序較全面的展示了Thread、List、Vector、Socket、ServerSocket、Input/OutpuStream、File Read/Write、Properties等核心API的用法,是初學(xué)者快速進(jìn)階的一個(gè)優(yōu)秀案例。 在涉及內(nèi)外網(wǎng)數(shù)據(jù)交換的網(wǎng)絡(luò)應(yīng)用系統(tǒng)開發(fā)中,我們經(jīng)常需要做端口映射,比如放在外部網(wǎng)絡(luò)主機(jī)上的程序要與內(nèi)部網(wǎng)絡(luò)上的某臺機(jī)器建主TC
49、P/IP連結(jié),如下圖(1)示: C機(jī)器可以與A機(jī)連通,但要與B機(jī)連通,由與不在同一網(wǎng)絡(luò),就無能為力了;這時(shí),就需在A機(jī)器上做交換或是轉(zhuǎn)發(fā),來接通C與B之間的TCP/IP連結(jié),即C機(jī)先與A機(jī)器建立Socket連結(jié),A再與B機(jī)建立連結(jié),然后由A在中間轉(zhuǎn)發(fā)C與B通信的數(shù)據(jù);B機(jī)器上可能運(yùn)行著數(shù)據(jù)庫,WebService等在Tcp/IP上通信的程序,而C機(jī)器必須訪問這些服務(wù)。這里A機(jī)器就充當(dāng)像現(xiàn)實(shí)生活中介紹人的角色,負(fù)責(zé)將C、B之間的通信數(shù)據(jù)流在Socket上轉(zhuǎn)發(fā);圖1 因此,A機(jī)需實(shí)現(xiàn)端口轉(zhuǎn)發(fā)功能,在Liunx上,可以通過配置IPTable由OS實(shí)現(xiàn),在本例中,我們將開發(fā)一個(gè)java實(shí)現(xiàn)的端口轉(zhuǎn)發(fā)程序jPortMap,此程序?qū)⑦\(yùn)行在A機(jī)器上,以實(shí)現(xiàn)轉(zhuǎn)發(fā)C與B之間通信的轉(zhuǎn)發(fā)。2.源碼下載及測試說明:從www.NetJ上下載源代碼解壓后,可看到如下目錄結(jié)構(gòu): 現(xiàn)在,你可以修改一下jPortMap.cfg中的配置,比如,想通過本機(jī)的地址上的8899端口轉(zhuǎn)發(fā)到56,則這樣配置:#本地I
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 3215-2025石油、石化和天然氣工業(yè)用離心泵
- GB/T 32219-2026筒式磨機(jī)鑄造磨段
- 創(chuàng)業(yè)培訓(xùn)教師授課信息反饋表
- 平臺穩(wěn)性操作員保密競賽考核試卷含答案
- 制材工安全文明測試考核試卷含答案
- 軋鋼精整工安全宣貫強(qiáng)化考核試卷含答案
- 橋梁支座試驗(yàn)培訓(xùn)
- 銀行內(nèi)部審計(jì)報(bào)告制度
- 酒店員工獎(jiǎng)懲與激勵(lì)機(jī)制制度
- 超市員工績效考核制度
- 北京市順義區(qū)2025-2026學(xué)年八年級上學(xué)期期末考試英語試題(原卷版+解析版)
- 中學(xué)生冬季防溺水主題安全教育宣傳活動(dòng)
- 2026年藥廠安全生產(chǎn)知識培訓(xùn)試題(達(dá)標(biāo)題)
- 初中九年級上一元二次方程計(jì)算練習(xí)題及答案詳解B2
- 中國涉外律師人才研究報(bào)告2025
- 冷庫防護(hù)制度規(guī)范
- 2026年生產(chǎn)管理崗入職性格測試題及答案
- 2026年bjt商務(wù)能力考試試題
- 廣東省廣州市番禺區(qū)2026屆高一數(shù)學(xué)第一學(xué)期期末聯(lián)考試題含解析
- 2026年廣東省佛山市高三語文聯(lián)合診斷性考試作文題及3篇范文:可以“重讀”甚至“重構(gòu)”這些過往
- 老年住院患者非計(jì)劃性拔管分析2026
評論
0/150
提交評論