隨筆 - 303  文章 - 883  trackbacks - 0
          <2007年3月>
          25262728123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          歡迎光臨! 
          閑聊 QQ:1074961813

          隨筆分類(357)

          我管理的群

          公共blog

          • n維空間
          • Email : java3d@126.com 群 : 12999758

          參與管理的論壇

          好友的blog

          我的其他blog

          朋友的網站

          搜索

          •  

          最新評論

          ?

          ??1 /*
          ??2 小高知宏?寫的書叫《TCP/IP?java篇》但我看起來,還想大都是應用層上的東西
          ??3 好象應該叫《TCP/IP?應用層?java篇》?有點搞不清他的書名是從何而來的,呵呵!
          ??4 這是小高知宏的Telnet的客戶端程序,接下來我們看看它是怎么實現的
          ??5 */
          ?
          ??6
          ??7 import ?java.net. * ;
          ??8 import ?java.io. * ;?
          ??9
          ?10 public ? class ?Telnet? {
          ?11 ?Socket?serverSocket;???????????????? // 創建服務器端SOCKET
          ?12 ? public ?OutputStream?serverOutput;
          ?13 ? public ?BufferedInputStream?serverInput;
          ?14 ?String?host;?????????????????? // 要連接的telnet服務器的地址或域名
          ?15 ? int ?port;????????????????????? // 要連接的服務器端口?
          ?16
          ?17 ? static ? final ? int ?DEFAULT_TELNET_PORT? = ? 23 ;?? // 定義默認的Telnet端口
          ?18 ??
          ?19 ?? // 構造telnet的連接參數(含端口,就是當你使用23以外的端口時,調用這個函數體),有點像C的數據結構
          ?20 ? public ?Telnet(String?host,? int ?port) {
          ?21 ?? this .host? = ?host;???? // 這里不解釋了THIS的用法前面講過
          ?22 ?? this .port? = ?port;
          ?23 ?}

          ?24 ?? // 定義默認端口23對應的函數體
          ?25 ? public ?Telnet(String?host) {
          ?26 ?? this (host,?DEFAULT_TELNET_PORT);?
          ?27
          ?28 ? // 建立連接,將在客戶端輸入的數據host+port轉換成數據流
          ?29 ? public ? void ?openConnection()
          ?30 ?? throws ?IOException,UnknownHostException
          ?31 ? {?????????????????????????????????????????????????????????????????????????????????????
          ?32 ??serverSocket? = ? new ?Socket(host,?port);????? // 創建Socket????????????????????????????????????????
          ?33 ??serverOutput? = ?serverSocket.getOutputStream();??? // 獲取輸入數據
          ?34 ??serverInput? = ? new ?BufferedInputStream(serverSocket.getInputStream());? // 裝換數據
          ?35 ?? if ?(port? == ?DEFAULT_TELNET_PORT) {?? // 判斷端口是不是23
          ?36 ???negotiation(serverInput,?serverOutput);? // 對輸出和輸入的數據進行分析,實現C/S端口的協商
          ?37 ??}

          ?38 ?}
          ?
          ?39
          ?40 ? public ? void ?main_proc()???? // 連接成功,啟動網絡線程
          ?41 ?? throws ?IOException
          ?42 ? {
          ?43 ?? try ? {
          ?44 ???
          ?45 ??? // 生成線程的StreamConnector類的對象stdin_to_socket和socket_to_stdout
          ?46 ??? // 從這里看出java是如何用類去創建對象的
          ?47 ???StreamConnector?stdin_to_socket? =
          ?48 ???? new ?StreamConnector(System.in,?serverOutput);???? // StreamConnector這個類在后面有定義
          ?49 ???StreamConnector?socket_to_stdout? =
          ?50 ???? new ?StreamConnector(serverInput,?System.out);
          ?51 ???
          ?52 ??? // 生成對象對應的stdin_to_socket和socket_to_stdout線程事件input_thread和output_thread
          ?53 ??? // 看到java的事件是如何從對象中產生的
          ?54 ???Thread?input_thread? = ? new ?Thread(stdin_to_socket);
          ?55 ???Thread?output_thread? = ? new ?Thread(socket_to_stdout);
          ?56 ???
          ?57 ??? // 看看java如何啟動或調用事件
          ?58 ???input_thread.start();
          ?59 ???output_thread.start();
          ?60 ??}

          ?61 ?? // 整個過程可能會產生異常,這里進行捕獲
          ?62 ?? catch (Exception?e) {
          ?63 ???System.err.print(e);
          ?64 ???System.exit( 1 );
          ?65 ??}

          ?66 ?}

          ?67 ?? // 定義用于協商的命令
          ?68 ??? // 如果一個數據既是static又是final,那么他會擁有一塊無法改變的存儲空間
          ?69 ? static ? final ? byte ?IAC? = ?( byte )? 255 ;
          ?70 ? static ? final ? byte ?DONT? = ?( byte )? 254 ;
          ?71 ? static ? final ? byte ?DO? = ?( byte )? 253 ;
          ?72 ? static ? final ? byte ?WONT? = ?( byte )? 252 ;
          ?73 ? static ? final ? byte ?WILL? = ?( byte )? 251 ;?
          ?74
          ?75 ?? // 利用NVT進行通信
          ?76 ?? /*
          ?77 ??NVT是一種抽象的設備,由打印機和鍵盤組成。用戶使用鍵盤鍵入的字符被轉發到服務器中,
          ?78 ??服務器再把數據返回給用戶,而NVT在打印機上將其輸出。它使用標準的回車與換行組合去
          ?79 ??終止行。NVT提供控制操作,這些操作支持過程中斷并丟棄多余的輸出。這些操作是通過使
          ?80 ??用IAC(Interpret?as?Command,解釋成命令)代碼發出的。IAC是一個單字節,由值255或十
          ?81 ??六進制0xff組成。IAC后面可以跟著一個單字節,用于發送控制代碼;或者后面跟著兩個或
          ?82 ??更多的字節,用于協商一選項。而為了發送已用于IAC的字節值255,可以通過一個特殊的字
          ?83 ??節序列來實現:連續發送兩個IAC。
          ?84 ??JAVA實現應用層的不少東西都是用他實現的?如:HTTP
          ?85 ?? */

          ?86 ??
          ?87 ? static ? void ?negotiation(
          ?88 ??BufferedInputStream?in,OutputStream?out)
          ?89 ?? throws ?IOException
          ?90 ? {
          ?91 ?? byte []?buff? = ? new ? byte [ 3 ];???? // 接收數據
          ?92 ?? while ( true )? {
          ?93 ???in.mark(buff.length);?? // 在此緩沖區的位置設置其標記
          ?94 ??? if ?(in.available()? >= ?buff.length)? {
          ?95 ????in.read(buff);??? // 讀取緩沖區內容
          ?96 ???? if ?(buff[ 0 ]? != ?IAC) {?? // 協商結束
          ?97 ?????in.reset();???? // 將此緩沖區的位置重新設置成以前標記的位置
          ?98 ????? return ;
          ?99 ????}
          ? else ? if ?(buff[ 1 ]? == ?DO)? {???? // 用于對DO的回應
          100 ?????buff[ 1 ]? = ?WONT;
          101 ?????out.write(buff);
          102 ????}

          103 ???}

          104 ??}

          105 ?}
          ?
          106
          107 ??? // 這里是主函數?
          108 ? public ? static ? void ?main(String[]?arg) {
          109 ?? try ? {
          110 ???Telnet?t? = ? null ;???? // 創建Telnet變量
          111 ??? switch ?(arg.length) {
          112 ??? case ? 1 :??? // 服務器名
          113 ????t? = ? new ?Telnet(arg[ 0 ]);
          114 ???? break ;
          115 ??? case ? 2 :?? // 服務器名+端口
          116 ????t? = ? new ?Telnet(arg[ 0 ],?Integer.parseInt(arg[ 1 ]));
          117 ???? break ;
          118 ??? default :??? // 如果輸入格式不對
          119 ????System.out.println(
          120 ????? " usage:?java?Telnet?<host?name>?{<port?number>} " );
          121 ???? return ;
          122 ???}

          123 ???t.openConnection();?? // 連接
          124 ???t.main_proc();???? // 創建線程
          125 ??}
          catch (Exception?e) {
          126 ???e.printStackTrace();
          127 ???System.exit( 1 );
          128 ??}

          129 ?}

          130 }
          ?
          131
          132 // 定義StreamConnector類
          133 // 定義前面的對象、事件的具體實現
          134 class ?StreamConnector? implements ?Runnable? {
          135 ?InputStream?src? = ? null ;
          136 ?OutputStream?dist? = ? null ;?
          137
          138 // 接收參數
          139 ? public ?StreamConnector(InputStream?in,?OutputStream?out) {
          140 ??src? = ?in;
          141 ??dist? = ?out;
          142 ?}

          143 // 用循環實現對數據流的讀寫
          144 ? public ? void ?run() {
          145 ?? byte []?buff? = ? new ? byte [ 1024 ];??? // 一次處理的最大數據量
          146 ?? while ?( true )? {
          147 ??? try ? {
          148 ???? int ?n? = ?src.read(buff);
          149 ???? if ?(n? > ? 0 )
          150 ?????dist.write(buff,? 0 ,?n);
          151 ???}

          152 ??? catch (Exception?e) {
          153 ????e.printStackTrace();
          154 ????System.err.print(e);
          155 ????System.exit( 1 );
          156 ???}

          157 ??}

          158 ?}

          159 }
          ?
          160


          地震讓大伙知道:居安思危,才是生存之道。
          posted on 2007-03-09 00:14 小尋 閱讀(862) 評論(0)  編輯  收藏 所屬分類: j2se/j2ee/j2me
          主站蜘蛛池模板: 台山市| 海门市| 安宁市| 平谷区| 盘锦市| 南康市| 田阳县| 息烽县| 岫岩| 大化| 那曲县| 德江县| 盐边县| 息烽县| 日照市| 凌云县| 新乡县| 桐城市| 英超| 彭山县| 龙井市| 呼图壁县| 康马县| 松阳县| 久治县| 枝江市| 台中市| 长丰县| 革吉县| 清水河县| 噶尔县| 马边| 方正县| 遂平县| 忻城县| 江川县| 日喀则市| 邢台市| 中西区| 神池县| 兴海县|