android socket 发送byte_如何正确地创建和销毁网络通讯程序中的Socket类的对象实例...
軟件項目實訓及課程設計指導——如何正確地創建和銷毀軟件應用系統中網絡通訊中的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設計模式中的構建者模式創建復合對象實例
如何合理地創建對象實例以降低程序類之間關系的耦合度
如何正確應用對象/關系映射技術實現系統持久層中各個DAO組件
總結
以上是生活随笔為你收集整理的android socket 发送byte_如何正确地创建和销毁网络通讯程序中的Socket类的对象实例...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 服务器驱动精灵_驱动精灵真的可以帮你安装
- 下一篇: 钩子函数和回调函数的区别