如何正確地創建和銷毀軟體應用系統中網絡通訊中的Socket對象實例

2020-12-22 楊教授工作室

軟體項目實訓及課程設計指導——如何正確地創建和銷毀軟體應用系統中網絡通訊中的Socket對象實例

1、基於TCP/IP協議的Socket通信相關的基礎知識

(1)TCP/IP(Transmission Control Protocol傳輸控制協議/Internet Protocol網間協議)

TCP/IP是目前Internet網絡中的主要協議,它定義了計算機和外設進行通信所使用的規則;TCP/IP網絡參考模型包括五個層次:應用層、傳輸層、網絡層、鏈路層、物理層。而ISO/OSI網絡參考模型則包括七個層次:應用層、表示層、會話層、傳輸層、網絡層、鏈路層、物理層。

(2)網絡通訊中數據傳輸的模式

面向連接(TCP)——比如生活中的打電話

無連接(UDP,User Datagram Protocol)——比如發郵件、簡訊等

(3)埠號

在網絡通訊中應用埠號達到區分服務的類別(該服務也就是伺服器端相關程序所提供的功能),從而允許伺服器端程序在同一時間內能夠進行多個不同的網絡會話,因為不同的網絡會話都有對應的服務埠號,彼此相互區分。

如:WWW服務的埠號為80,telnet服務的埠號為21,ftp服務的埠號為23,smtp服務的埠號為25,pop3服務的埠號為110等。

在程序中應用埠號時需要注意埠號的範圍,埠號其實是一個16位無符號整數,數值範圍是0-65535;低於256的埠號保留給標準的應用程式使用,比如pop3的埠號就是110。

2、Java語言中提供基於TCP/IP協議的Socket通信的技術支持

(1)了解什麼是Socket(套接字)

網絡中雙向通訊程序中的某一端稱為一個Socket,一個程序將一段信息寫入Socket中,該Socket將這段信息發送給另外一個Socket中,使這段信息能傳送到其他程序中。

(2)Java提供客戶端套接字Socket類和伺服器端套接字ServerSocket類

在JDK系統API庫java.net包中提供有客戶端套接字Socket類和伺服器端套接字ServerSocket類,軟體應用系統的開發人員可以應用在網絡通信的客戶端程序中構建出Socket類的對象實例,也就是當客戶端程序需要與伺服器端程序進行通訊時,客戶端程序需要在客戶機程序中創建一個Socket對象,Socket類有多種不同形式的構造方法。

在JDK API中與Socket通信有關的各個接口和功能類都定義在java.net包中,而在對應的伺服器端程序中則需要創建出ServerSocket類的對象實例。

在Java程序中構建Socket類的對象實例需要提供伺服器端主機的IP位址以及伺服器端相關程序所提供的對外服務的埠號,從而使得不同的客戶端程序應用IP位址可以區分不同的伺服器主機,同時再通過埠號進一步區分在同一伺服器主機中可能提供不同的功能服務。

(3)基於Socket通訊的主要過程

通訊的主要過程包括Socket的建立、監聽、連接、發送數據和接收數據等環節。

3、Socket通訊實現中客戶/伺服器端通訊的主要方式及工作原理

(1)客戶/伺服器端通訊的主要方式

在網絡通訊中的客戶端和伺服器端之間的通訊方式主要有如下的兩種方式:

「一對一」,也就是一個伺服器對應一個客戶機,此種通訊方式由於通訊的效率低下,目前已經不再應用;

「一對多」,也就是一個伺服器對應多個連接的客戶機。為此,在伺服器相關的程序中一般都要應用多線程的技術才能使得伺服器程序可以同時響應不同的客戶端程序的請求——也就是需要採用一個伺服器端程序進程但構建出多個不同的線程。

(2)客戶/伺服器端通訊的工作原理如下示圖所示

4、正確地應用Socket類的構造方法創建出Socket類的對象實例

如下示圖為JDK API幫助文檔中所提供的Socket類的各種構造方法的定義,但在Socket類中兩個常用的構造方法分別是 Socket(InetAddress addr, int port) 和 Socket(String host, int port),它們都能夠創建出一個基於Socket的連接伺服器端流的套接字對象。

在程序中可以通過構造方法Socket(InetAddress addr, int port)內的第1個參數InetAddress類對象實例addr獲得伺服器端主機的IP位址,而在程序中通過構造方法Socket(String host, int port)中的第1個字符串類型參數host可以獲得代表伺服器端主機的名稱字符串。

這兩個構造方法都聲明有拋出UnknownHostException異常類對象。下面為構造Socket類對象實例的代碼片段示例:

try {

Socket oneSocketObject =new Socket(「伺服器IP位址」,」埠號」);

}

catch(UnknownHostException e){

}

catch (Ioexception e){

}

5、如何獲得伺服器端主機及客戶端主機的IP位址

由於Socket類對象實例可以出現在網絡通訊中的客戶端程序和伺服器端程序中,因此在客戶端和伺服器端不同的程序中通過調用Socket類對象實例中的同一個方法但獲得的結果卻是不同的,讀者在程序中應用時需要加以區分。

(1)在客戶端程序代碼中通過調用Socket類對象實例中的getInetAddress()方法可以獲得遠程伺服器端主機的IP位址,而通過調用Socket類對象實例中的getPort()可以獲得遠程伺服器端主機的埠號。

(2)在伺服器端程序代碼中通過調用Socket類對象實例中的getInetAddress()方法可以獲得遠程客戶端主機的IP位址。

(3)在伺服器端程序代碼中通過調用Socket類中的getLocalAddress()可以獲得伺服器端本機的IP位址,而通過調用Socket類中的getLocalPort()可以獲得伺服器端本機的埠號。

(4)在客戶端程序代碼中通過調用Socket類中的getLocalAddress()可以獲得客戶端本機的IP位址,而通過調用Socket類中的getLocalPort()可以獲得客戶端本機的埠號(此埠號其實就是連接到伺服器的埠號)。

6、獲得伺服器的主機名和對應的IP位址的程序代碼示例

(1)依據伺服器的主機名獲得伺服器的IP位址

InetAddress類存儲遠程系統的IP位址,如下代碼片段示例是根據所提供的伺服器端主機名稱字符串"WWW-XUMIF9WPKIP "(可以為其它主機名稱字符串或者包括本機"localhost"字符串等)獲得對應的IP位址。

try{

InetAddress serverInetAddress =

InetAddress.getByName("WWW-XUMIF9WPKIP ");

System.out.println("伺服器主機IP位址為:"+

serverInetAddress.toString());

}

catch (UnknownHostException e){

}

對其中的serverInetAddress.toString()的調用代碼也可以改用如下的語句System.out.println("伺服器主機IP位址為:"+ serverInetAddress.getHostAddress());顯示出伺服器主機IP位址。程序代碼執行的結果參見如下示圖所示。

(2)依據伺服器主機的IP位址獲得伺服器的主機名

在InetAddress類中提供有static 靜態類型的public static InetAddress getByAddress(byte[] addr) throws UnknownHostException方法,該方法根據給定伺服器主機IP 地址(由4位元組的數組參數表示)返回 InetAddress 類型的對象實例。

如下代碼示例是假定伺服器主機的IP位址為192.168.0.1,然後再依據該IP位址獲得對應的主機名稱字符串的代碼片段示例。

try{

byte[] serverHostIPByteArray = new byte[] { (byte) 192, (byte) 168, 0, 1 };

InetAddress serverInetAddress =

InetAddress.getByAddress(serverHostIPByteArray);

System.out.println("伺服器主機名稱為:"+

serverInetAddress.getHostName ());

}

catch (UnknownHostException e){

}

7、如何正確地關閉Socket類的對象實例以及時釋放所佔的系統資源

當構造出Socket類的對象實例時,Java虛擬機JVM系統同樣也需要為它分配一定的系統資源。因此,在軟體應用系統程序中如果不再需要Socket類的對象實例時,應該及時地將它關閉掉以釋放所佔用的系統資源。

關閉Socket類的對象實例分為主動關閉(Active closure)和被動關閉(Passive closure)兩種情況。前者是指由本地客戶端主機主動發起的關閉行為;而後者則是指本地主機檢測到遠程伺服器主機發起的關閉行為之後,相應地也作出對應關閉的回應,從而關閉整個通訊中的連接。

下面為關閉Socket類對象實例的代碼片段示例,並且要將這些程序代碼放在finally 關鍵字所標識的語句塊中以保證在程序中即使出現異常也能夠正常地被執行:

finally {

try{

/** 下面代碼中的oneSocketInputObject對象代表Socket輸入流對象實例 */

oneSocketInputObject.close();

/** 下面代碼中的oneSocketOutputObject對象代表Socket輸出流對象實例 */

oneSocketOutputObject.close();

/** 下面代碼中的oneSocketObject對象代表Socket流對象實例 */

oneSocketObject.close();

}

catch(IOException e){

}

}

由於在通訊過程中需要發送和接收數據,因此在客戶端還需要構造出Socket輸入流對象實例(如示例代碼中的oneSocketInputObject)和Socket輸出流對象實例(如示例代碼中的oneSocketOutputObject),在關閉Socket類對象實例之前首先應該分別關閉與Socket相關的所有輸入/輸出流對象實例,以釋放所有的資源。

而且還要注意關閉代碼的順序——與Socket相關的所有輸入/輸出IO流對象實例應該要先關閉,然後再關閉Socket類對象實例本身。

儘管Java語言中提供有垃圾自動回收的機制,Socket通訊過程中所佔用的各種網絡資源最終是會被Java虛擬機JVM系統釋放的。但是為了能夠有效地利用系統的資源,建議讀者還是按照合理的順序在程序代碼中主動釋放這些資源,以避免出現內存洩漏現象。

在程序中如何正確地創建和銷毀軟體應用系統中文件IO流對象實例

課程設計指導——如何應用Java反射技術靈活地創建程序類對象實例

如何應用GOF設計模式中的構建者模式創建複合對象實例

如何應用GOF設計模式中的創建型模式實現鬆耦合地創建對象實例

如何合理地創建對象實例以降低程序類之間關係的耦合度

相關焦點

  • 如何正確地創建和銷毀軟體應用系統中JDBC資料庫連接對象實例
    軟體項目實訓及課程設計指導——如何正確地創建和銷毀軟體應用系統中JDBC資料庫連接對象實例1、Java語言中提供有訪問資料庫系統的JDBC編程接口Java 資料庫連接技術(JDBC,Java DataBase Connectivity)其實是將Java語言與標準的
  • 如何合理地創建對象實例以降低程序類之間關係的耦合度
    OOP編程開發中軟體應用系統的開發人員所必須要面對的問題,軟體應用系統中的業務活動是由各個對象實例之間的相互交互而構成的。但頻繁地創建對象實例不僅會降低軟體應用系統的整體運行的性能,也增加了不必要的程序類之間的耦合關係。如下示圖中的Employee類與其中的TimeCard類之間就存在有「一對多」 形式的關聯關係,因為在Employee類的對象實例中耦合有TimeCard類的對象實例。因此,如何正確和合理地創建出類的對象實例?
  • 課程設計指導——如何應用Java反射技術靈活地創建程序類對象實例
    軟體項目實訓及課程設計指導——如何應用Java反射技術靈活地創建程序類的對象實例1、如何應用屬性配置文件實現對系統中的配置信息進行讀寫操作Java中的屬性配置文件主要可以作為軟體應用系統及項目的配置文件,比如許多J2EE的開源框架系統中都提供了屬性配置文件作為該應用框架的對外配置文件
  • 如何應用策略設計模式分離JDBC資料庫連接中的外部環境信息
    軟體項目實訓及課程設計指導——如何應用策略設計模式分離JDBC資料庫連接中的外部環境信息1、什麼是策略(Strategy)設計模式策略設計模式把「算法」(也就是軟體應用系統中的業務規則或者待實現的功能等)和「環境」(封裝軟體應用系統在實際應用時的場景)相互分離
  • 如何優化Web應用數據訪問實現方式以提高軟體應用系統的響應性能
    軟體項目實訓及課程設計指導——如何優化Web應用數據訪問實現方式以提高軟體應用系統的響應性能在軟體應用系統中離不開數據訪問和數據處理兩個方面的功能,而數據處理之前首先要進行數據訪問,也就是只有快速地獲得了數據,才能進行下一步的數據處理。
  • pro-face 觸控螢幕與PLC通訊在淨水系統中應用實例
    該軟體為GP-PRO/PB3 for Windows (支持Windows 98 / Me / 2000 / XP 系統),目前最新的版本為 Version 7.01。(本文附件中包括了淨水系統的PLC程序)在選擇系統組成後,我們需要對系統進行編程,這裡講到的是對可編程序觸控螢幕的編程。
  • 如何正確地設計J2EE應用系統持久層中的各個組件結構及組件間關係
    軟體項目實訓及課程設計指導——如何正確地設計J2EE應用系統持久層中的各個組件結構及關係1、了解J2EE應用系統數據持久層中的各個組件類的類型在J2EE系統平臺下的軟體應用系統的數據持久層,一般都包含有如下的各個組件類:實體類、數據訪問對象類(包括接口和對應的實現類
  • 如何保證軟體應用系統架構設計結果的可擴展性和可重用性(上篇)
    當然,要能夠達到這樣的軟體系統架構設計結果,需要設計人員充分地應用面向對象技術中的抽象機制,對軟體應用系統中共性的部分進行充分的抽取。而為了能夠保證軟體應用系統的系統架構設計結果是可擴展的,必須要應用「封裝」和「隔離」的設計手段、並且遵守一些相關的設計原則和應用典型的設計模式。
  • 如何在Web應用系統表示層開發實現中應用Velocity模板技術
    軟體項目實訓及課程設計指導——如何在Web應用系統表示層開發實現中應用Velocity模板技術1、分離Web表示層的數據處理和展現邏輯的常見的應用技術分離Web表示層的數據處理和展現邏輯是目前企業級的Web應用系統開發中表現層組件開發實現中的基本實現目標。
  • EffectiveJava-1-創建和銷毀對象
    可以不用在每次調用時都創建一個新的對象,可以使用預先構建好的對象,或將構建好的對象緩存起來,進行重複利用,適用於經常請求創建相同對象,並且創建對象的代價很高,如常見的單例模式寫法就是對這一點的應用;實例受控的類:能為重複的調用返回相同的類,有助於類控制某個時刻哪些實例應該存在,功能如下:1.確保它是一個Singleton或者是不可實例化的;2.使得不可變的類不會存在兩個相等的實例
  • 應用XML+XSLT技術分離Web應用系統中表示層數據和樣式的實例
    軟體項目實訓及課程設計指導——應用XML+XSLT技術分離Web應用系統中表示層數據和樣式的實例1、在J2EE應用系統中應用XSLT實現XML文檔轉換的基本過程(1)首先,創建出目標XML格式文檔文件,該XML格式文檔文件代表應用系統中的數據模型
  • Socket網絡編程核心API深入分析(一):bind函數
    ()函數,bind的系統調用過程,bind是如何處理埠衝突的,面試的時候你就這樣講。編程TCP協議的調用流程如下:深入分析bind函數我從應用層出發,沿著網絡協議棧,從bind()的系統調用、到Socket層實現,最終到它的TCP層實現。
  • 如何在Web應用中實現Velocity 與Struts2框架相互集成的應用實例
    軟體項目實訓及課程設計指導——如何在Web應用系統中實現Velocity 與Struts2框架相互集成的應用實例1、Struts 2應用框架提供對 Velocity 和 FreeMarker 模板引擎的支持在Struts 2應用框架中不僅繼續保留有對Velocity
  • 如何應用Web頁面靜態化技術以提高J2EE Web應用系統的響應性能
    因此,經過靜態化技術轉換處理後的結果Web頁面能夠快速地響應用戶的HTTP請求,而且還能夠大大地減少對Web伺服器系統資源的消耗。當然,為了能夠達到靜態化的功能實現目標,軟體應用系統的開發人員可以在Web應用系統的開發中應用各種模板技術——比如Velocity模板、FreeMarker模板技術等。
  • 三菱plc與觸控螢幕通訊實例
    且具有完整的性能和通訊功能等擴展性。如果考慮安裝空間和成本是一種理想的選擇。   FX1N系列:   是三菱電機推出的功能強大的普及型PLC。具有擴展輸入輸出,模擬量控制和通訊、連結功能等擴展性。是一款廣泛應用於一般的順序控制三菱PLC。   FX2N系列:   在當時,是三菱PLC是FX家族中最先進的系列。
  • 軟體項目實訓及課程設計指導——如何實現面向服務的系統架構設計
    面向服務的軟體應用系統的系統體系架構能夠提供靈活的業務處理功能實現,而業務功能實現的靈活性一方面能夠保證軟體應用系統可以對業務變更快速和有效地進行響應。這個特性對於許多企業來說,可以提高企業的競爭力;另一方面,軟體應用系統的系統架構設計師能夠創建一個業務靈活的系統架構——該系統架構是一個既可以滿足當前的業務需要,也還能夠滿足未來的業務需求的體系結構。
  • 如何應用EhCache緩存框架提高J2EE Web應用系統持久層的響應性能
    軟體項目實訓及課程設計指導——如何應用EhCache緩存框架提高應用系統持久層響應性能1、在Web應用系統中應用持久層相關的緩存框架在Java應用程式開發實現和J2EE Web應用系統的設計和開發實現中,軟體應用系統的設計和開發實現人員可以在系統的表示層和系統的持久層中充分地應用緩存機制和相應實現技術能夠大大地提高
  • LIS系統通訊程序的原理與實現
    Winsock API一般採用異步方式通訊,此時,不能用類似於for 語句的循環來實現對多組數據的發送,更不能用循環語句來接收數據。比如,你可以用for 語句來實現若干文件的複製,這很普遍也很正常,但在 Socket編程以及大多數網絡應用編程中都是行不通的,因網絡通訊的基本方式是請求和應答。在Unix平臺下大多採用阻塞方式開發,此時可以利用一些傳統的方法。
  • Java中的IO與NIO
    有了Java NIO之後,就可以花少量的線程來處理大量的連接,在上圖中,Selector是對Linux下的select/poll/epoll的包裝,Channel是可IO操作的硬體、文件、socket、其他程序組件的包裝,我們可以把Channel看成是網絡連接,網絡連接上主要有connect、accept、read和write等事件,Selector負責監聽這些事件的發生,一旦某個Channel
  • 軟體項目實訓及課程設計指導——實體類結構和類關係的設計示例
    通常把業務領域中的各種名詞——例如客戶、訂單、商品等信息可以作為應用系統中的實體域對象。在如下示圖中的各個資料庫表所體現出的數據對象都可以設計為對應的實體類,然後在數據訪問邏輯組件中訪問和操作這些實體類的對象實例。