隨筆 - 303  文章 - 883  trackbacks - 0
          <2007年2月>
          28293031123
          45678910
          11121314151617
          18192021222324
          25262728123
          45678910

          歡迎光臨! 
          閑聊 QQ:1074961813

          隨筆分類(357)

          我管理的群

          公共blog

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

          參與管理的論壇

          好友的blog

          我的其他blog

          朋友的網站

          搜索

          •  

          最新評論

          注意:文章中使用的代碼沒有公用類,如直接使用會報錯。若想使用,請自己創建一個PUBLIC,如不知如何創建,建議回頭看看JAVA基礎部分,本文著重解釋原理。

          原文作者:于洪斌、馬俊光、車雪松

          一、java與網絡通信

            java是一門適合于分布式計算環境、尤其是Internet程序設計的語言。這不僅僅在于java具有很好的安全性和可移植性,還在于java為Internet編程提供了豐富的網絡類庫支持。利用這些網絡類庫,可以輕松編寫多種類型的網絡通信程序。

          ?

            TCP/IP協議是當今最流行的協議,也是Internet的基礎協議,它代表的是一個協議集合。除傳輸控制協議TCP和網際協議IP外,TCP/IP協議集還包括其他一些協議,如UDP、FTP、UUCP、ICMP等。

            一般的TCP/IP網絡數據通信主要可分為兩種不同的通信協議,一種是面向連接的通信協議,這種傳輸方式在數據傳送前必須先在兩端建立連接,并且所傳送的數據不會丟失,這種方式稱為TCP,也稱為Stream;另一種方式則是面向非連接方式,即傳送數據前,并不必先建立連接,而是將所要傳送的數據包成一個分組再傳送,使用這種方式,由于沒有額外的控制,所以傳送的數據可能丟掉。這種方式稱為UDP,也稱為Datagram。

          ?

            TCP和UDP都是傳輸層上的通信協議,也是一般TCP/IP網絡上最常使用的通信協議,且各有其用途,如TCP較可靠,所以用在不允許數據丟失的應用上。而UDP則較多應用于處理速度要求較快、數據傳輸可靠性要求不是很高的應用上,如數據廣播。在java中也支持這兩種不同的協議,對它們的支持是以類庫的形式提供的。通過Socket和ServerSocket類提供了對TCP通信的支持,對于UDP通信則提供了DatagramSocket和DatagramPacket類。它們都包含在java.net類庫中。本文中,我們主要探討TCP通信程序的寫法,而UDP通信程序的寫法與此類似。

          ?

             二、通信程序的編寫

            在進一步討論之前,我們先來看看Socket和ServerSocket類的定義(表1)和(表2),關于這兩個類的詳細內容請見sun公司的JDK或microsoft公司VJ++ 1.1的聯機文檔。

            

            要使用上面所提供的功能編寫網絡通信程序,我們可以將要通信的兩端分成服務器和客戶機端,即建立所謂的客戶機/服務器編程模式。在服務器端必須先建立一個ServerSocket對象,然后等待客戶機端的訪問。而在客戶機端,則是建立一個Socket對象直接跟服務器端連接,如果連接建立成功,則服務器端便會產生一個Socket對象,然后我們就可以利用這個Socket對象跟客戶機端的Socket對象溝通了。此時在服務器和客戶機之間建立了一條可靠連接,客戶機和服務器可以在這條連接上可靠的傳送數據。客戶機發出請求,服務器監聽來自客戶機的請求,并為客戶機提供相應的服務。

          ?

            基于上述原理,我們編寫了簡單的客戶機/服務器模式的網絡通信程序。在服務器端,服務器監聽客戶機的請求,為每個客戶機請求建立Socket連接,從而為客戶機提供服務。而所提供的服務只是讀取來自客戶機的一行文本,并把它發回給客戶機。以下是服務器端的通信程序。

            

          ??1 import ?java.io. * ;?
          ??2
          ??3    import ?java.net. * ;?
          ??4
          ??5    class ?javaserver? extends ?Thread? {??????? // javaserver開始?
          ??6
          ??7   ?ServerSocket?server;?
          ??8
          ??9   ? public ?javaserver()? {?
          ?10
          ?11   ? try ? {?
          ?12
          ?13   ?server? = ? new ?ServerSocket( 600 );?????????? // 創建服務器端進程ServerSocket端口600
          ?14   ?}
          ?
          ?15
          ?16   ? catch (IOException?e)? {?
          ?17
          ?18   ?System.out.println( " Cannot?create?Server " );?????????? // 創建失敗?
          ?19
          ?20   ?System.exit( 0 );?
          ?21
          ?22   ?}
          ?
          ?23
          ?24   ?System.out.println( " Now?socket?server?will?Start " );???? // 創建成功?
          ?25
          ?26   ? this .start();?????????????????????????????????????????? // 啟動ServerSocket?
          ?27
          ?28   ?}
          ?
          ?29
          ?30   ? public ? void ?run()? {?
          ?31
          ?32   ? try ? {?
          ?33
          ?34   ? while ?( true )? {?
          ?35
          ?36   ?Socket?client? = ?server.accept();??? // 創建server.accept用于接收客戶端信息,同時?
          ?37
          ?38   ?service?ss? = ? new ?service(client);??? // ?該語句會在每次接收前做一次。把信息放到變量ss中?
          ?39
          ?40   ?}
          ?
          ?41
          ?42   ?}
          ?
          ?43
          ?44   ? catch (IOException?e)? {?
          ?45
          ?46   ?System.out.println( " cannot?provide?service?! " );???????????????? // 出問題,捕獲異常?
          ?47
          ?48   ?System.exit( 1 );?
          ?49
          ?50   ?}
          ?
          ?51
          ?52   ?}
          ?
          ?53
          ?54   ? public ? static ? void ?main(String?args[]) {?????? // 主函數,所有函數將在這里被調用?
          ?55
          ?56   ?String?data;???????????????????????????????????????????????????????????????????
          ?57
          ?58   ?DataInputStream?KeyInput;?
          ?59
          ?60   ? new ?javaserver();?
          ?61
          ?62   ?KeyInput? = ? new ?DataInputStream(System.in);??????? // 用于接收客戶端數據流?
          ?63
          ?64   ? try ? {?
          ?65
          ?66   ?data? = ?KeyInput.readLine();?????????????????????? // 將收到的數據流寫入data變量?
          ?67
          ?68   ?}
          ?
          ?69
          ?70   ? catch ?(IOException?e) {?
          ?71
          ?72   ? return ;?
          ?73
          ?74   ?}
          ?
          ?75
          ?76   ? if ?(data.equals( " quit " ))?System.exit( 1 );???????????????????
          ?77
          ?78   ?}
          ?
          ?79
          ?80   }
          ???????????????????????????????????????????????? // javaserver結束?
          ?81
          ?82   ? class ?service? extends ?Thread? {???????????????? // 服務器代碼重點之處開始?
          ?83
          ?84   ?String?data;?
          ?85
          ?86   ?DataInputStream?InputS;??????????????????? // 接收數據變量?
          ?87
          ?88   ?PrintStream?OutputS;?????????????????????? // 傳出數據變量?
          ?89
          ?90   ?Socket?Client;?????
          ?91
          ?92   ? public ?service(Socket?ClientSocket)? {?
          ?93
          ?94   ?Client? = ?ClientSocket;?
          ?95
          ?96   ? try ? {?
          ?97
          ?98   ?InputS? = ? new ?DataInputStream(Client.getInputStream());??????????
          ?99 ???????? // 接收客戶端數據
          100 ????????
          101   ?OutputS? = ? new ?PrintStream?(Client.getOutputStream());?
          102 ???????? // 向客戶端發送數據
          103 ????????
          104   ?}
          ?
          105
          106   ? catch ?(IOException?e) {?
          107
          108   ?System.out.println( " Cannot?Connect?with?Client?! " );?
          109
          110   ? return ;?
          111
          112   ?}
          ?
          113
          114   ? this .start();?????????? // 連接成功開始,啟動進程?
          115
          116   ?}
          ?
          117
          118   ? public ? void ?run() {?
          119
          120   ? try ? {?
          121
          122   ? while ?( true ) {???????????????????????????????? // 創建循環接客戶端收數據?
          123
          124   ?data? = ?InputS.readLine();????????????
          125
          126   ? if ?(data? == ? null )? break ;?????????????????????? // 判斷接收是否完成?
          127
          128   ? else ? {?
          129
          130   ?OutputS.println(data);????????????????????????? // 接收完畢的話,輸出?
          131
          132   ?System.out.println( " From?Client:? " ? + ?data);??????????? // 打印輸出?
          133
          134   ?}
          ?
          135
          136   ?}
          ?
          137
          138   ?}
          ?
          139
          140   ? catch ?(IOException?e) {?
          141
          142   ?System.out.println( " Read?Data?error " );?
          143
          144   ?}
          ?
          145
          146   ? try ? {?
          147
          148   ?Client.close();????????????????????????????????????? // 關閉與客戶端的通信?
          149
          150   ?}
          ?
          151
          152   ? catch ?(IOException?e) {?
          153
          154   ?System.out.println( " Cannot?close?socket " );???????????????? // 關閉socket?
          155
          156   ?}
          ?
          157
          158   ?}
          ?
          159
          160   }
          ?
          161
          162

          ?

             在上面的程序中,我們使用了多線程機制。javaserver和service對象本身都是一個線程。javaserver對象首先創建一個ServerSocket對象,并啟動線程的運行。它的run()方法用于監聽來自客戶機的連接。每當有一個新的客戶機連接時,ServerSocket就會創建一個新的Socket類實例,并創建一個service對象,同時啟動這個對象的線程。每個service對象用于完成與客戶機通信、提供服務的任務。這樣服務器可以同時與多個客戶機連接,同時為多個客戶機提供服務。當從標準輸入中接收到quit字符串時,服務器退出運行。

            在客戶機端,首先創建一個Socket對象,用于與服務器通信。它從標準輸入中讀取數據,把這些數據傳給服務器,再從服務器讀取應答信息,然后把這些應答信息寫到標準輸出。當讀取了5行的數據后,客戶機程序將退出運行。以下是客戶機端的通信程序。

             

          ?1 import ?java.io. * ;?
          ?2
          ?3    import ?java.net. * ;?
          ?4
          ?5    class ?javaclient? {?
          ?6
          ?7   ? public ? static ? void ?main(String?args[]) {?
          ?8
          ?9   ?String?data;???????????????????????????????????????? // 與服務器端變量data變量對應?
          10
          11   ?Socket?Client;?????????????????????????????????????? // (下同)??
          12
          13   ?DataInputStream?InputS;?
          14
          15   ?DataInputStream?KeyS;?
          16
          17   ?PrintStream?OutputS;?
          18
          19   ? int ?i? = ? 0 ;?
          20
          21   ? try ? {?
          22
          23   ?Client? = ? new ?Socket( " 172.17.3.2 " , 600 );??????????
          24 ????????????? // 創建客戶端Socket進程,發送對象172.17.3.2端口600?
          25
          26   ?InputS? = ? new ?DataInputStream(Client.getInputStream());?
          27 ?????????????? // 接收服務器端數據流?
          28
          29   ?OutputS? = ? new ?PrintStream?(Client.getOutputStream());?
          30 ?????????????? // 打印服務器端數據流
          31   
          32 ?????KeyS? = ? new ?DataInputStream(System.in);?
          33 ?????????????? // 將數據傳給本地系統。(想深入了解的請看jdk中的原代碼的DataInputStream部分)
          34 ????????
          35   ?}
          ?
          36
          37   ? catch (IOException?e) {?
          38
          39   ?System.out.println( " Cannot?Connect?with?Server " );????????? // 出錯提示:無法連接到服務器?
          40
          41   ? return ;?
          42
          43   ?}
          ?
          44
          45   ? try ? {?
          46
          47   ? while ?(i < 5 ) {?????????????? // 創建循環接收數據
          48 ?
          49   ?data? = ?KeyS.readLine();??????????? // 將數據讀入data中?
          50
          51   ?OutputS.println(data);???????????? // 打印數據?
          52
          53   ?System.out.println( " ECHO?From?
          54
          55   ?Server: " +?InputS.readLine());?????????//打印接收到的服務器端數據流?
          56
          57   ?i ++ ;?
          58
          59   ?}
          ?
          60
          61   ?}
          ?
          62
          63   ? catch (IOException?e)? {?
          64
          65   ?System.out.println( " IOException??Happened " );?
          66
          67   ?}
          ?
          68
          69   ? try {?
          70
          71   ?System.out.println( " Now?will??end?this?program " );?
          72
          73   ?Client.close();???????????????????????? // 關閉客戶端進程?
          74
          75   ?}
          ?
          76
          77   ? catch (IOException?e) {?
          78
          79   ?System.out.println( " system?cannot?close?socket " );?
          80 ?????????????
          81   ?}
          ?
          82
          83   ?}
          ?
          84
          85   }
          ?
          86
          87

             三、結束語

            通過以上的討論可知,用java語言編寫網絡通信程序非常簡單,這主要是因為java語言本身就是一門面向網絡編程的語言。java提供了多個可用于訪問標準Internet協議的類庫,從而支持多種Internet協議,包括:FTP,HTTP,NNTP和WWW等,這極大的簡化了網絡程序設計,可以比較方便的編寫出功能完善的應用程序。

            以上只是我們對java語言進行網絡通信程序設計的粗淺討論。利用java語言進行程序設計的好處不一而論,愿我們能起到拋磚引玉的作用。



          地震讓大伙知道:居安思危,才是生存之道。
          posted on 2007-02-24 12:31 小尋 閱讀(1099) 評論(0)  編輯  收藏 所屬分類: j2se/j2ee/j2menetwork
          主站蜘蛛池模板: 龙南县| 东乌珠穆沁旗| 枞阳县| 来宾市| 汾阳市| 郓城县| 石柱| 嘉祥县| 个旧市| 黄浦区| 新兴县| 轮台县| 女性| 玉田县| 敖汉旗| 安福县| 颍上县| 金华市| 南昌市| 阜宁县| 巍山| 贡山| 纳雍县| 界首市| 鸡泽县| 和平县| 响水县| 明星| 蒙山县| 扶余县| 登封市| 谢通门县| 龙门县| 南投县| 梁平县| 墨竹工卡县| 罗江县| 祥云县| 贵德县| 濮阳市| 太和县|