Java使網(wǎng)絡(luò)編程更方便、簡(jiǎn)潔。它提供了各種Socket類,讀者只要了解這
些類的構(gòu)造和相關(guān)的方法,就可以輕松的編寫網(wǎng)絡(luò)程序。而無(wú)論任何網(wǎng)絡(luò)
程序都是運(yùn)行在一定的協(xié)議體系中的,了解這些協(xié)議的基本內(nèi)容對(duì)于更好
的理解各種Socket類和方法都很有幫助。下面將介紹在Internet中占主導(dǎo)
地位的TCP/IP協(xié)議。
14.1? TCP/IP協(xié)議
TCP/IP協(xié)議是整個(gè)網(wǎng)絡(luò)通信的核心協(xié)議。其中TCP協(xié)議運(yùn)行在客戶終端上,
是集成在操作系統(tǒng)內(nèi)的一套協(xié)議軟件,它的任務(wù)是在網(wǎng)絡(luò)上的兩個(gè)機(jī)器之
間實(shí)現(xiàn)端到端的、可靠的數(shù)據(jù)傳輸功能。IP協(xié)議運(yùn)行在組成網(wǎng)絡(luò)的核心設(shè)
備路由器上,它也是集成在系統(tǒng)內(nèi)的一層協(xié)議軟件,負(fù)責(zé)將數(shù)據(jù)分組從源
端發(fā)送到目的端,通過(guò)對(duì)整個(gè)網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)的理解為分組的發(fā)送選擇路由
。值得注意的是TCP協(xié)議運(yùn)行在客戶的主機(jī)中,是操作系統(tǒng)的一個(gè)組件,一
般操作系統(tǒng)會(huì)默認(rèn)安裝給協(xié)議軟件,而IP協(xié)議既運(yùn)行在客戶主機(jī)中也運(yùn)行
在網(wǎng)絡(luò)設(shè)備中,在我們的主機(jī)中,查看安裝的TCP/IP協(xié)議軟件如圖主機(jī)中
的TCP/IP屬性所示。
14.1.1? IP協(xié)議和IP地址
計(jì)算機(jī)網(wǎng)絡(luò)中的每臺(tái)運(yùn)行了IP協(xié)議的主機(jī),都具有一個(gè)IP地址,該地址標(biāo)
示網(wǎng)絡(luò)中的一臺(tái)主機(jī)。IP地址采用點(diǎn)分十進(jìn)制方法表示。如192.168.2.1,
IP地址是一個(gè)32位的二進(jìn)制序列,點(diǎn)分的每個(gè)部分占一個(gè)字節(jié),使用十進(jìn)
制表達(dá)。顯然每個(gè)部分的最大不超過(guò)255,因?yàn)槎M(jìn)制的8個(gè)1(11111111)
用十進(jìn)制表達(dá)就是255。
IP地址由網(wǎng)絡(luò)部分和主機(jī)部分,網(wǎng)絡(luò)部分表示一個(gè)通信子網(wǎng),給子網(wǎng)內(nèi)的
主機(jī)可以不通過(guò)路由器而直接通信,如一個(gè)公司辦公室的局域網(wǎng),主機(jī)部
分標(biāo)識(shí)該通信子網(wǎng)內(nèi)的主機(jī)。
14.1.2? TCP協(xié)議和端口
在整個(gè)網(wǎng)絡(luò)中,分組的傳輸過(guò)程中會(huì)發(fā)生很多難以預(yù)料的故障,如主機(jī)
down機(jī)或系統(tǒng)問(wèn)題、網(wǎng)絡(luò)連線中斷、網(wǎng)絡(luò)交換設(shè)備掉電或網(wǎng)絡(luò)擁塞,這些
為問(wèn)題的出現(xiàn)都可能造成分組的丟失或損壞。那么保障分組可靠地到達(dá)目
的地是IP協(xié)議無(wú)法解決的。此時(shí)需要它的上層協(xié)議TCP來(lái)處理。
TCP協(xié)議實(shí)現(xiàn)可靠通信的基礎(chǔ)是采用了握手機(jī)制實(shí)現(xiàn)了數(shù)據(jù)的同步傳輸,即
在通信的雙方發(fā)送數(shù)據(jù)前首先建立鏈接,協(xié)商一些參數(shù),如發(fā)送的數(shù)據(jù)字
節(jié)數(shù)量、緩沖區(qū)大小等。一旦鏈接建立再傳送數(shù)據(jù),并且對(duì)于收到的每一
個(gè)分組進(jìn)行確認(rèn),這樣很好的保證了數(shù)據(jù)的可靠傳輸。
14.1.3? 客戶/服務(wù)器通信模型
客戶/服務(wù)器通信模型通常稱為C/S模型(Client/Server模型)。在這種通
信模型中有兩個(gè)軟件主體,一個(gè)是客戶程序,一個(gè)是服務(wù)器程序。我們通
常稱為客戶端和服務(wù)器端。通信的過(guò)程是客戶端向服務(wù)器端發(fā)出請(qǐng)求,例
如訪問(wèn)FTP服務(wù)器下載文件,這個(gè)下載請(qǐng)求就由客戶端發(fā)出,而服務(wù)器接收
到請(qǐng)求后處理請(qǐng)求,把數(shù)據(jù)返回客戶端。完成一次通信過(guò)程。圖所示模型
是簡(jiǎn)單的客戶/服務(wù)器通信模型。該模型展示了概要的通信模式。
14.2? UDP協(xié)議
UDP(User Datagram Protocol)協(xié)議稱為用戶數(shù)據(jù)報(bào)協(xié)議。該協(xié)議運(yùn)行在
TCP/IP模型的傳輸層,該協(xié)議可以直接封裝成IP分組,不需要事先建立鏈
接就可以發(fā)送這些封裝好的IP分組。
一個(gè)UDP報(bào)文有兩個(gè)端口即源機(jī)器端口和目的機(jī)器端口、UDP長(zhǎng)度、UDP校驗(yàn)
和UDP凈荷組成,通過(guò)目的端口目的主機(jī)的傳輸層就知道把該報(bào)文遞交給那
個(gè)處理進(jìn)程。而源端口值得從目標(biāo)主機(jī)返回的UDP報(bào)文到達(dá)源主機(jī)后可以正
確的提交給上層進(jìn)程處理。
14.3? 基于Java的客戶/服務(wù)器程序
本章介紹的Java網(wǎng)絡(luò)編程建立在TCP/IP協(xié)議基礎(chǔ)上,使用Socket套接字編
寫網(wǎng)絡(luò)通信程序。使用套接字編程可使程序員把主要精力集中在應(yīng)用層,
集中于需要解決的問(wèn)題領(lǐng)域,而至于傳輸層和網(wǎng)絡(luò)層,以及更底層的細(xì)節(jié)
則不用考慮,這些問(wèn)題Socket套接字全部處理。也就是說(shuō)使用套接字使程
序員看不到底層的通信細(xì)節(jié),而只是在應(yīng)用層使用Socket完成兩個(gè)主機(jī)之
間的通信。
這里需要首先介紹一下Socket再回到我們要討論的問(wèn)題。
14.3.1? Socket及其原語(yǔ)
Socket概念來(lái)源于BerkeleyUNIX中使用的TCP socket(套接字),可以把它
看做一個(gè)通信實(shí)體,負(fù)責(zé)完成位于不同主機(jī)上的應(yīng)用程序間通信。該套接
字提供了一組原語(yǔ)(一組最基本的操作)保證客戶端和服務(wù)器端順利地建
立通信鏈接并傳輸數(shù)據(jù),最后釋放鏈接。這組原語(yǔ)已經(jīng)廣泛應(yīng)用在網(wǎng)絡(luò)程
序設(shè)計(jì)中。理解了這組原語(yǔ)對(duì)于理解客戶/服務(wù)器通信過(guò)程的建立和釋放很
有幫助。表列出了8個(gè)原語(yǔ)。
14.3.2? 創(chuàng)建服務(wù)器
創(chuàng)建服務(wù)器使得服務(wù)器同客戶端傳輸數(shù)據(jù)需要三個(gè)基本步驟:
(1)創(chuàng)建ServerSocket對(duì)象。
(2)阻塞服務(wù)進(jìn)程、啟動(dòng)監(jiān)聽(tīng)。
(3)創(chuàng)建流并讀、寫數(shù)據(jù)。
14.3.3? 創(chuàng)建客戶端
創(chuàng)建客戶端程序與創(chuàng)建服務(wù)器程序略有區(qū)別,顯然服務(wù)器需要監(jiān)聽(tīng)服務(wù)請(qǐng)
求,而客戶端只需要啟動(dòng)鏈接請(qǐng)求,所以創(chuàng)建客戶端關(guān)鍵是創(chuàng)建一個(gè)
Socket對(duì)象。下面代碼是Client客戶程序中創(chuàng)建Socket對(duì)象的過(guò)程。
private static String serverAddress=”localhost”;
private static int port = 8080;
Socket socket = new Socket (serverAddress,port);
14.4? Socket類詳解
Socket套接字在客戶、服務(wù)器通信模型中扮演著十分重要的角色,它就如
服務(wù)器和客戶端的代理,完成雙方應(yīng)用程序發(fā)送和接收數(shù)據(jù)的任務(wù)。客戶
建立和服務(wù)器的鏈接而創(chuàng)建了Socket,服務(wù)器一旦接收客戶的鏈接請(qǐng)求也
返回一個(gè)Socket,之后這兩個(gè)Socket就可以收發(fā)數(shù)據(jù)了。
本章重點(diǎn)介紹如何創(chuàng)建一個(gè)Socket,這里主要講解該類的幾個(gè)構(gòu)造函數(shù),
并給出各自的實(shí)例代碼,演示不同的Socket對(duì)象創(chuàng)建方法。同時(shí)介紹建立
Socket鏈接時(shí)的常見(jiàn)異常的相關(guān)分析,使得讀者知道在使用中常見(jiàn)的鏈接
問(wèn)題的性質(zhì)。Socket含有豐富的信息,這些信息是建立鏈接的必要條件,
同時(shí)也是數(shù)據(jù)傳輸?shù)那疤幔菊聦?duì)Socket的幾個(gè)getXXX()函數(shù)的介紹使得
讀者充分認(rèn)識(shí)Socket到底包含了什么。最后介紹關(guān)閉鏈接的方式和注意事
項(xiàng)。
14.4.1? 創(chuàng)建Socket
Socket類的幾種構(gòu)造函數(shù)如下,其區(qū)別在于參數(shù)的不同,為用戶創(chuàng)建
Socket對(duì)象提供了靈活性。
(1)Socket():該構(gòu)造函數(shù)沒(méi)有任何參數(shù),創(chuàng)建沒(méi)有建立鏈接的Socket對(duì)
象,該對(duì)象包含系統(tǒng)的默認(rèn)屬性。
(2)Socket(InetAddress address , int port) throws IOException
該構(gòu)造函數(shù)創(chuàng)建一個(gè)流Socket,并且鏈接到指定IP地址的指定端口。
(3)Socket(String host, int port) throws UnknownHostException
IOException
該構(gòu)造函數(shù)創(chuàng)建一個(gè)流Socket,并且鏈接到指定主機(jī)的指定端口。
(4)Socket(InetAddress address,int port,InetAddress localadd,int
localport) throws IOException
該構(gòu)造函數(shù)創(chuàng)建一個(gè)Socket對(duì)象,鏈接到指定的遠(yuǎn)端地址的指定端口。
(5)Socket(String host,int port,InetAddress localadd,int
localport) throws IOException
該構(gòu)造函數(shù)創(chuàng)建一個(gè)流Socket,并且鏈接到指定名字的主機(jī)的指定端口。
如果指定的主機(jī)名為null,相當(dāng)于通過(guò)InetAddress.getByName(null)獲得
的地址(即localhost),同時(shí)該方法綁定本地主機(jī)的IP地址和服務(wù)端口號(hào)
。
14.4.2? Socket類的getXX ()方法
Socket類提供了getXX()方法,使用這些方法可以獲得Socket對(duì)象的豐富信
息,如建立Socket鏈接必須的主機(jī)IP地址和進(jìn)程端口號(hào)。一旦建立了鏈接
,Socket提供了輸入輸出流方法來(lái)讀取服務(wù)器的數(shù)據(jù),接收從服務(wù)器返回
的數(shù)據(jù)。下面詳細(xì)介紹經(jīng)常使用個(gè)Socket類各種getXX()方法。
public InetAddress getInetAddress()
該方法返回建立了Socket鏈接的遠(yuǎn)端Socket的地址,如果沒(méi)有建立鏈接則
返回null.
public InetAddress getLocalAddress()
該方法返回建立了Socket鏈接的本地地址。
public int getPort()
該方法返回建立了Socket鏈接的遠(yuǎn)端服務(wù)的端口號(hào)。
public int getLocalPort()
該方法返回建立了Socket鏈接的本地服務(wù)端口號(hào)。
publicInputStream getInputStream() throws IOException
該方法返回當(dāng)前Socket的輸入流
publicOutputStream getOutputStream() throws IOException
該方法返回當(dāng)前Socket的輸入流
14.4.3? Socket類的setXX ()方法
Socket類提供了豐富的各種set類型方法,這是傳輸時(shí)需要考慮的參數(shù)如發(fā)
送和接收數(shù)據(jù)緩沖區(qū)的大小,長(zhǎng)時(shí)間等待關(guān)閉鏈接,是否處理緊急數(shù)據(jù),
是否使用換成那個(gè)機(jī)制等。本節(jié)將詳細(xì)介紹常用的set類型方法。讀者需要
了解這些方法的功能,和使用時(shí)機(jī),而方法本身的使用很簡(jiǎn)單,相信讀者
看后很容易掌握。
14.4.4? 關(guān)閉Socket
但建立Socket通信的雙方一旦通信結(jié)束,需要及時(shí)關(guān)閉Socket,這樣就可
以及時(shí)的釋放鏈接占用的資源如端口號(hào)、綁定的IP地址。Socket對(duì)象調(diào)用
close()方法關(guān)閉Socket通信,此時(shí)對(duì)象的輸入輸入流不再進(jìn)行輸入輸出操
作。
如果需要立即釋放服務(wù)端口和IP地址,需要事先調(diào)用setReuseAddress
(boolean on)方法。如下代碼所示。
socket.setReuseAddress(true);
如果需要立即拋棄未發(fā)送完畢的數(shù)據(jù),需要事先調(diào)用setSoLinger(boolean
on,int time)方法。如下代碼所示。
socket. setSoLinger(true,0);
14.5? SocketServer類
在11.3.1節(jié)我們學(xué)習(xí)了JDK的常用工具,其中在bin目錄下的工具最為有用
,在計(jì)算機(jī)上編譯和執(zhí)行Java程序時(shí)需要知道編譯和執(zhí)行程序的工具。
14.5.1? 創(chuàng)建SocketServer
Java提供了靈活的構(gòu)造函數(shù)來(lái)創(chuàng)建SocketServer對(duì)象,該對(duì)象負(fù)責(zé)在服務(wù)
器端監(jiān)聽(tīng)客戶端請(qǐng)求。下面依次介紹構(gòu)造函數(shù)和使用方式。
(1)public void ServerSocket() throws IOException
該構(gòu)造函數(shù)創(chuàng)建一個(gè)不帶參數(shù)的默認(rèn)構(gòu)造方法。顯然該構(gòu)造函數(shù)不與任何
斷口綁定,這樣創(chuàng)建的對(duì)象無(wú)法直接調(diào)用accept()方法類監(jiān)聽(tīng)接入的訪問(wèn)
,必須綁定一個(gè)服務(wù)端口客戶端程序才可以訪問(wèn)到服務(wù)器程序。
(2)public ServerSocket(int port ) throws IOException
該構(gòu)造函數(shù)創(chuàng)建一個(gè)帶端口參數(shù)的ServerSocket對(duì)象,默認(rèn)的服務(wù)器地址
為本機(jī)的IP地址。
(3)public void ServerSocket(int port, int connectNumber) throws
IOExcepiton
該構(gòu)造函數(shù)有兩個(gè)參數(shù),第一個(gè)參數(shù)指定服務(wù)器的服務(wù)端口,第二個(gè)參數(shù)
指定服務(wù)器管理鏈接請(qǐng)求的的數(shù)量。
14.5.2? SocketServer類的兩個(gè)重要方法
SocketServer類的兩個(gè)重要方法如下所示。
(1)SocketServer 類accept()方法
當(dāng)客戶端向服務(wù)器發(fā)出請(qǐng)求時(shí),該請(qǐng)求保存在服務(wù)器主機(jī)操作系統(tǒng)維護(hù)的
請(qǐng)求隊(duì)列中,accept()方法負(fù)責(zé)從該請(qǐng)求隊(duì)列中取出一個(gè)最早的請(qǐng)求,該
方法返回一個(gè)Socket對(duì)象,服務(wù)器通過(guò)該對(duì)象實(shí)現(xiàn)與客戶端的雙向可靠通
信。
(2)SocketServer類close()方法
該方法關(guān)閉當(dāng)前服務(wù)器和客戶端的所有鏈接,釋放鏈接占用的資源如服務(wù)
端口,一般情況下不需要顯示的調(diào)用該方法,服務(wù)器程序退出時(shí),操作系
統(tǒng)回自動(dòng)釋放端口資源。顯示關(guān)閉SocketServer對(duì)象的方式如下所示。
ServerSocket serverSocket = New ServerSocket(8080);?
serverSocket.close();
14.5.3? 讀取SockerServer信息
ServerSocket類提供了一系列的get方法來(lái)獲得 ServerSocket的信息。如下
所示。
public InetAddress getInetAddress()
該方法返回建立了Socket鏈接的遠(yuǎn)端 Socket的地址,如果沒(méi)有建立鏈接則
返回null。
public InetAddress getLocalAddress()
該方法返回建立了Socket鏈接的本地地址。
public int getPort()
該方法返回建立了Socket鏈接的遠(yuǎn)端服務(wù)的端口號(hào)。
public int getLocalPort()
該方法返回建立了Socket鏈接的本地服務(wù)端口號(hào)。
14.5.3? 讀取SockerServer信息
publicInputStream getInputStream() throws IOException
該方法返回當(dāng)前Socket的輸入流。
publicOutputStream getOutputStream() throws IOException
該方法返回當(dāng)前Socket的輸入流。
其中常用的兩個(gè)方法如下所示:
Public InetAddress getInetAddress()
該方法返回該服務(wù)器綁定的IP地址,如果創(chuàng)建 ServerSocket對(duì)象時(shí)采用默
認(rèn)的地址,則是服務(wù)器的本地地址,如果在創(chuàng)建對(duì)象時(shí)顯示指定了服務(wù)器
地址,則getInetAddress()方法返回的是指定的地址。
Public int getLocalPort();
該方法返回服務(wù)端口,如果用戶沒(méi)有顯示設(shè)置該端口,則操作系統(tǒng)會(huì)隨即
分配一個(gè)端口,否則返回用戶指定的端口。
14.6? 數(shù)據(jù)報(bào)通信
在TCP/IP協(xié)議族中,UDP協(xié)議與TCP協(xié)議都是處在傳輸層。而UDP協(xié)議是一種
無(wú)鏈接協(xié)議,即在建立通信的雙方無(wú)須事先建立聯(lián)系,只要需要發(fā)送數(shù)據(jù)
只管發(fā)送,不需要考慮對(duì)方是否接受或網(wǎng)絡(luò)是否可靠。它發(fā)送的每個(gè)數(shù)據(jù)
報(bào)稱為UDP報(bào)文,稱為UDP數(shù)據(jù)報(bào)。每個(gè)數(shù)據(jù)報(bào)相互獨(dú)立,各自包含完整的
目的地地址,源地址和相應(yīng)的端口號(hào)。數(shù)據(jù)報(bào)在網(wǎng)絡(luò)的傳輸路徑取決于網(wǎng)
絡(luò)自身的狀況,至于能否到達(dá)目的地或到達(dá)后報(bào)文的正確性都難以保證。
在對(duì)方收到UDP報(bào)文后也不會(huì)作出任何反饋告訴發(fā)送方當(dāng)前的狀態(tài)。顯然這
種方式無(wú)法保證數(shù)據(jù)的正確性,也無(wú)法處理丟失報(bào)文的情況。
14.6.1? 數(shù)據(jù)報(bào)通信簡(jiǎn)介
基于Java的數(shù)據(jù)報(bào)通信主要依靠?jī)蓚€(gè)類來(lái)完成,一個(gè)是
java.net.DatagramSocket類,一個(gè)是java.net.DatagramPacket類。其中
DatagramPacket表示要發(fā)送或接受的數(shù)據(jù)報(bào),而DatagramSocket負(fù)責(zé)接收
和發(fā)送數(shù)據(jù)報(bào),如下代碼所示。
1 //創(chuàng)建一個(gè)數(shù)據(jù)報(bào)
2 DatagramPacket packet = new DatagramPacket(new byte
[1024],1024);
3 //等待接收數(shù)據(jù)報(bào), 如果沒(méi)有接收到數(shù)據(jù),進(jìn)程阻塞。
4? socket.receive(packet);
5 // 創(chuàng)建要發(fā)送的數(shù)據(jù)報(bào)
6 DatagramPacket Packet = new DatagramPacket(outputData,
7???????
outputData.length,remoteIP,8080);
8 //發(fā)出數(shù)據(jù)報(bào)
9 socket.send(Packet);
14.6.2? DatagramPacket類簡(jiǎn)介
(1)構(gòu)造函數(shù)
使用UDP協(xié)議發(fā)送和接收數(shù)據(jù),需要在程序中表示數(shù)據(jù)報(bào)以調(diào)用
DatagramSocket的receive()和send()方法來(lái)接收和發(fā)送數(shù)據(jù)報(bào),
DatagramPacket對(duì)象就是程序中的數(shù)據(jù)報(bào),該類通過(guò)構(gòu)造函數(shù)創(chuàng)建不同的
數(shù)據(jù)報(bào)。其構(gòu)造函數(shù)分為兩類,一類創(chuàng)建用于發(fā)送的數(shù)據(jù)報(bào),一類用于接
收的數(shù)據(jù)報(bào)。
(2)DatagramPacket類的連個(gè)重要方法
14.6.3? DatagramSocket類簡(jiǎn)介
DatagramSocket類負(fù)責(zé)接收和發(fā)送數(shù)據(jù)報(bào),每個(gè) DatagramSocket對(duì)象會(huì)綁
定一個(gè)服務(wù)端口,這個(gè)端口可以是顯示設(shè)置的,也可以采用匿名端口,匿
名端口由操作系統(tǒng)隨機(jī)分配。UDP數(shù)據(jù)報(bào)在兩個(gè)DatagramSocket的對(duì)象實(shí)體
間傳輸。
編寫數(shù)據(jù)報(bào)方式的客戶、服務(wù)器程序時(shí),首先需要在客戶方和服務(wù)器方建
立一個(gè)DatagramSocket對(duì)象,用來(lái)接收或發(fā)送數(shù)據(jù)報(bào)。接收和發(fā)送的數(shù)據(jù)
報(bào)由DatagramPacket類構(gòu)造。
14.6.4? 實(shí)現(xiàn)數(shù)據(jù)報(bào)通信
在學(xué)習(xí)過(guò)了數(shù)據(jù)報(bào)通信的機(jī)制,以及java.net.DatagramSocket類和
java.net.Datagram
類之后。我們通過(guò)一個(gè)具體里的基于UDP協(xié)議的客戶服務(wù)器程序說(shuō)明
DatagramSocket類來(lái)發(fā)送和接收數(shù)據(jù)的過(guò)程。
服務(wù)器程序的主機(jī)地址為本機(jī)地址,服務(wù)端口號(hào)為8080,程序啟動(dòng)后等待
接收數(shù)據(jù)而阻塞,直到接收到UDP數(shù)據(jù)報(bào)才終止阻塞狀態(tài)。接收到數(shù)據(jù)后,
顯示在控制臺(tái),并且把收到的數(shù)據(jù)再發(fā)送會(huì)客戶端。服務(wù)器程序如代碼所
示。
14.7? 本章習(xí)題
(1)學(xué)完本章中,讀者需要回答:
簡(jiǎn)述IP 協(xié)議的作用,ip協(xié)議工作在OSI參考模型的那一個(gè)層
TCP 協(xié)議的的作用?什么是一個(gè)網(wǎng)絡(luò)鏈接。
簡(jiǎn)述客戶/服務(wù)器通信模型。
如何通過(guò)Socket類創(chuàng)建客戶端程序
如何通過(guò) SocketServer類實(shí)現(xiàn)服務(wù)器端程序。
解釋什么是數(shù)據(jù)報(bào)通信。
如何通過(guò)DatagramPacket類創(chuàng)建數(shù)據(jù)報(bào)
如何通過(guò)DatagramSocket類實(shí)現(xiàn)數(shù)據(jù)報(bào)通信。
(2)注意事項(xiàng)。
1.本章的基本通信模型是C/S模型,在繼續(xù)學(xué)習(xí)客戶端/服務(wù)器應(yīng)用程序設(shè)
計(jì)前首先要理解該通信模型。
2.本章讀者一定要掌握最簡(jiǎn)單的通過(guò)Socket類SocketServer類實(shí)現(xiàn)客戶端
/服務(wù)器應(yīng)用程序的設(shè)計(jì)開(kāi)發(fā)。
3.掌握數(shù)據(jù)報(bào)通信的原理和具體實(shí)現(xiàn)方法。
些類的構(gòu)造和相關(guān)的方法,就可以輕松的編寫網(wǎng)絡(luò)程序。而無(wú)論任何網(wǎng)絡(luò)
程序都是運(yùn)行在一定的協(xié)議體系中的,了解這些協(xié)議的基本內(nèi)容對(duì)于更好
的理解各種Socket類和方法都很有幫助。下面將介紹在Internet中占主導(dǎo)
地位的TCP/IP協(xié)議。
14.1? TCP/IP協(xié)議
TCP/IP協(xié)議是整個(gè)網(wǎng)絡(luò)通信的核心協(xié)議。其中TCP協(xié)議運(yùn)行在客戶終端上,
是集成在操作系統(tǒng)內(nèi)的一套協(xié)議軟件,它的任務(wù)是在網(wǎng)絡(luò)上的兩個(gè)機(jī)器之
間實(shí)現(xiàn)端到端的、可靠的數(shù)據(jù)傳輸功能。IP協(xié)議運(yùn)行在組成網(wǎng)絡(luò)的核心設(shè)
備路由器上,它也是集成在系統(tǒng)內(nèi)的一層協(xié)議軟件,負(fù)責(zé)將數(shù)據(jù)分組從源
端發(fā)送到目的端,通過(guò)對(duì)整個(gè)網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)的理解為分組的發(fā)送選擇路由
。值得注意的是TCP協(xié)議運(yùn)行在客戶的主機(jī)中,是操作系統(tǒng)的一個(gè)組件,一
般操作系統(tǒng)會(huì)默認(rèn)安裝給協(xié)議軟件,而IP協(xié)議既運(yùn)行在客戶主機(jī)中也運(yùn)行
在網(wǎng)絡(luò)設(shè)備中,在我們的主機(jī)中,查看安裝的TCP/IP協(xié)議軟件如圖主機(jī)中
的TCP/IP屬性所示。
14.1.1? IP協(xié)議和IP地址
計(jì)算機(jī)網(wǎng)絡(luò)中的每臺(tái)運(yùn)行了IP協(xié)議的主機(jī),都具有一個(gè)IP地址,該地址標(biāo)
示網(wǎng)絡(luò)中的一臺(tái)主機(jī)。IP地址采用點(diǎn)分十進(jìn)制方法表示。如192.168.2.1,
IP地址是一個(gè)32位的二進(jìn)制序列,點(diǎn)分的每個(gè)部分占一個(gè)字節(jié),使用十進(jìn)
制表達(dá)。顯然每個(gè)部分的最大不超過(guò)255,因?yàn)槎M(jìn)制的8個(gè)1(11111111)
用十進(jìn)制表達(dá)就是255。
IP地址由網(wǎng)絡(luò)部分和主機(jī)部分,網(wǎng)絡(luò)部分表示一個(gè)通信子網(wǎng),給子網(wǎng)內(nèi)的
主機(jī)可以不通過(guò)路由器而直接通信,如一個(gè)公司辦公室的局域網(wǎng),主機(jī)部
分標(biāo)識(shí)該通信子網(wǎng)內(nèi)的主機(jī)。
14.1.2? TCP協(xié)議和端口
在整個(gè)網(wǎng)絡(luò)中,分組的傳輸過(guò)程中會(huì)發(fā)生很多難以預(yù)料的故障,如主機(jī)
down機(jī)或系統(tǒng)問(wèn)題、網(wǎng)絡(luò)連線中斷、網(wǎng)絡(luò)交換設(shè)備掉電或網(wǎng)絡(luò)擁塞,這些
為問(wèn)題的出現(xiàn)都可能造成分組的丟失或損壞。那么保障分組可靠地到達(dá)目
的地是IP協(xié)議無(wú)法解決的。此時(shí)需要它的上層協(xié)議TCP來(lái)處理。
TCP協(xié)議實(shí)現(xiàn)可靠通信的基礎(chǔ)是采用了握手機(jī)制實(shí)現(xiàn)了數(shù)據(jù)的同步傳輸,即
在通信的雙方發(fā)送數(shù)據(jù)前首先建立鏈接,協(xié)商一些參數(shù),如發(fā)送的數(shù)據(jù)字
節(jié)數(shù)量、緩沖區(qū)大小等。一旦鏈接建立再傳送數(shù)據(jù),并且對(duì)于收到的每一
個(gè)分組進(jìn)行確認(rèn),這樣很好的保證了數(shù)據(jù)的可靠傳輸。
14.1.3? 客戶/服務(wù)器通信模型
客戶/服務(wù)器通信模型通常稱為C/S模型(Client/Server模型)。在這種通
信模型中有兩個(gè)軟件主體,一個(gè)是客戶程序,一個(gè)是服務(wù)器程序。我們通
常稱為客戶端和服務(wù)器端。通信的過(guò)程是客戶端向服務(wù)器端發(fā)出請(qǐng)求,例
如訪問(wèn)FTP服務(wù)器下載文件,這個(gè)下載請(qǐng)求就由客戶端發(fā)出,而服務(wù)器接收
到請(qǐng)求后處理請(qǐng)求,把數(shù)據(jù)返回客戶端。完成一次通信過(guò)程。圖所示模型
是簡(jiǎn)單的客戶/服務(wù)器通信模型。該模型展示了概要的通信模式。
14.2? UDP協(xié)議
UDP(User Datagram Protocol)協(xié)議稱為用戶數(shù)據(jù)報(bào)協(xié)議。該協(xié)議運(yùn)行在
TCP/IP模型的傳輸層,該協(xié)議可以直接封裝成IP分組,不需要事先建立鏈
接就可以發(fā)送這些封裝好的IP分組。
一個(gè)UDP報(bào)文有兩個(gè)端口即源機(jī)器端口和目的機(jī)器端口、UDP長(zhǎng)度、UDP校驗(yàn)
和UDP凈荷組成,通過(guò)目的端口目的主機(jī)的傳輸層就知道把該報(bào)文遞交給那
個(gè)處理進(jìn)程。而源端口值得從目標(biāo)主機(jī)返回的UDP報(bào)文到達(dá)源主機(jī)后可以正
確的提交給上層進(jìn)程處理。
14.3? 基于Java的客戶/服務(wù)器程序
本章介紹的Java網(wǎng)絡(luò)編程建立在TCP/IP協(xié)議基礎(chǔ)上,使用Socket套接字編
寫網(wǎng)絡(luò)通信程序。使用套接字編程可使程序員把主要精力集中在應(yīng)用層,
集中于需要解決的問(wèn)題領(lǐng)域,而至于傳輸層和網(wǎng)絡(luò)層,以及更底層的細(xì)節(jié)
則不用考慮,這些問(wèn)題Socket套接字全部處理。也就是說(shuō)使用套接字使程
序員看不到底層的通信細(xì)節(jié),而只是在應(yīng)用層使用Socket完成兩個(gè)主機(jī)之
間的通信。
這里需要首先介紹一下Socket再回到我們要討論的問(wèn)題。
14.3.1? Socket及其原語(yǔ)
Socket概念來(lái)源于BerkeleyUNIX中使用的TCP socket(套接字),可以把它
看做一個(gè)通信實(shí)體,負(fù)責(zé)完成位于不同主機(jī)上的應(yīng)用程序間通信。該套接
字提供了一組原語(yǔ)(一組最基本的操作)保證客戶端和服務(wù)器端順利地建
立通信鏈接并傳輸數(shù)據(jù),最后釋放鏈接。這組原語(yǔ)已經(jīng)廣泛應(yīng)用在網(wǎng)絡(luò)程
序設(shè)計(jì)中。理解了這組原語(yǔ)對(duì)于理解客戶/服務(wù)器通信過(guò)程的建立和釋放很
有幫助。表列出了8個(gè)原語(yǔ)。
14.3.2? 創(chuàng)建服務(wù)器
創(chuàng)建服務(wù)器使得服務(wù)器同客戶端傳輸數(shù)據(jù)需要三個(gè)基本步驟:
(1)創(chuàng)建ServerSocket對(duì)象。
(2)阻塞服務(wù)進(jìn)程、啟動(dòng)監(jiān)聽(tīng)。
(3)創(chuàng)建流并讀、寫數(shù)據(jù)。
14.3.3? 創(chuàng)建客戶端
創(chuàng)建客戶端程序與創(chuàng)建服務(wù)器程序略有區(qū)別,顯然服務(wù)器需要監(jiān)聽(tīng)服務(wù)請(qǐng)
求,而客戶端只需要啟動(dòng)鏈接請(qǐng)求,所以創(chuàng)建客戶端關(guān)鍵是創(chuàng)建一個(gè)
Socket對(duì)象。下面代碼是Client客戶程序中創(chuàng)建Socket對(duì)象的過(guò)程。
private static String serverAddress=”localhost”;
private static int port = 8080;
Socket socket = new Socket (serverAddress,port);
14.4? Socket類詳解
Socket套接字在客戶、服務(wù)器通信模型中扮演著十分重要的角色,它就如
服務(wù)器和客戶端的代理,完成雙方應(yīng)用程序發(fā)送和接收數(shù)據(jù)的任務(wù)。客戶
建立和服務(wù)器的鏈接而創(chuàng)建了Socket,服務(wù)器一旦接收客戶的鏈接請(qǐng)求也
返回一個(gè)Socket,之后這兩個(gè)Socket就可以收發(fā)數(shù)據(jù)了。
本章重點(diǎn)介紹如何創(chuàng)建一個(gè)Socket,這里主要講解該類的幾個(gè)構(gòu)造函數(shù),
并給出各自的實(shí)例代碼,演示不同的Socket對(duì)象創(chuàng)建方法。同時(shí)介紹建立
Socket鏈接時(shí)的常見(jiàn)異常的相關(guān)分析,使得讀者知道在使用中常見(jiàn)的鏈接
問(wèn)題的性質(zhì)。Socket含有豐富的信息,這些信息是建立鏈接的必要條件,
同時(shí)也是數(shù)據(jù)傳輸?shù)那疤幔菊聦?duì)Socket的幾個(gè)getXXX()函數(shù)的介紹使得
讀者充分認(rèn)識(shí)Socket到底包含了什么。最后介紹關(guān)閉鏈接的方式和注意事
項(xiàng)。
14.4.1? 創(chuàng)建Socket
Socket類的幾種構(gòu)造函數(shù)如下,其區(qū)別在于參數(shù)的不同,為用戶創(chuàng)建
Socket對(duì)象提供了靈活性。
(1)Socket():該構(gòu)造函數(shù)沒(méi)有任何參數(shù),創(chuàng)建沒(méi)有建立鏈接的Socket對(duì)
象,該對(duì)象包含系統(tǒng)的默認(rèn)屬性。
(2)Socket(InetAddress address , int port) throws IOException
該構(gòu)造函數(shù)創(chuàng)建一個(gè)流Socket,并且鏈接到指定IP地址的指定端口。
(3)Socket(String host, int port) throws UnknownHostException
IOException
該構(gòu)造函數(shù)創(chuàng)建一個(gè)流Socket,并且鏈接到指定主機(jī)的指定端口。
(4)Socket(InetAddress address,int port,InetAddress localadd,int
localport) throws IOException
該構(gòu)造函數(shù)創(chuàng)建一個(gè)Socket對(duì)象,鏈接到指定的遠(yuǎn)端地址的指定端口。
(5)Socket(String host,int port,InetAddress localadd,int
localport) throws IOException
該構(gòu)造函數(shù)創(chuàng)建一個(gè)流Socket,并且鏈接到指定名字的主機(jī)的指定端口。
如果指定的主機(jī)名為null,相當(dāng)于通過(guò)InetAddress.getByName(null)獲得
的地址(即localhost),同時(shí)該方法綁定本地主機(jī)的IP地址和服務(wù)端口號(hào)
。
14.4.2? Socket類的getXX ()方法
Socket類提供了getXX()方法,使用這些方法可以獲得Socket對(duì)象的豐富信
息,如建立Socket鏈接必須的主機(jī)IP地址和進(jìn)程端口號(hào)。一旦建立了鏈接
,Socket提供了輸入輸出流方法來(lái)讀取服務(wù)器的數(shù)據(jù),接收從服務(wù)器返回
的數(shù)據(jù)。下面詳細(xì)介紹經(jīng)常使用個(gè)Socket類各種getXX()方法。
public InetAddress getInetAddress()
該方法返回建立了Socket鏈接的遠(yuǎn)端Socket的地址,如果沒(méi)有建立鏈接則
返回null.
public InetAddress getLocalAddress()
該方法返回建立了Socket鏈接的本地地址。
public int getPort()
該方法返回建立了Socket鏈接的遠(yuǎn)端服務(wù)的端口號(hào)。
public int getLocalPort()
該方法返回建立了Socket鏈接的本地服務(wù)端口號(hào)。
publicInputStream getInputStream() throws IOException
該方法返回當(dāng)前Socket的輸入流
publicOutputStream getOutputStream() throws IOException
該方法返回當(dāng)前Socket的輸入流
14.4.3? Socket類的setXX ()方法
Socket類提供了豐富的各種set類型方法,這是傳輸時(shí)需要考慮的參數(shù)如發(fā)
送和接收數(shù)據(jù)緩沖區(qū)的大小,長(zhǎng)時(shí)間等待關(guān)閉鏈接,是否處理緊急數(shù)據(jù),
是否使用換成那個(gè)機(jī)制等。本節(jié)將詳細(xì)介紹常用的set類型方法。讀者需要
了解這些方法的功能,和使用時(shí)機(jī),而方法本身的使用很簡(jiǎn)單,相信讀者
看后很容易掌握。
14.4.4? 關(guān)閉Socket
但建立Socket通信的雙方一旦通信結(jié)束,需要及時(shí)關(guān)閉Socket,這樣就可
以及時(shí)的釋放鏈接占用的資源如端口號(hào)、綁定的IP地址。Socket對(duì)象調(diào)用
close()方法關(guān)閉Socket通信,此時(shí)對(duì)象的輸入輸入流不再進(jìn)行輸入輸出操
作。
如果需要立即釋放服務(wù)端口和IP地址,需要事先調(diào)用setReuseAddress
(boolean on)方法。如下代碼所示。
socket.setReuseAddress(true);
如果需要立即拋棄未發(fā)送完畢的數(shù)據(jù),需要事先調(diào)用setSoLinger(boolean
on,int time)方法。如下代碼所示。
socket. setSoLinger(true,0);
14.5? SocketServer類
在11.3.1節(jié)我們學(xué)習(xí)了JDK的常用工具,其中在bin目錄下的工具最為有用
,在計(jì)算機(jī)上編譯和執(zhí)行Java程序時(shí)需要知道編譯和執(zhí)行程序的工具。
14.5.1? 創(chuàng)建SocketServer
Java提供了靈活的構(gòu)造函數(shù)來(lái)創(chuàng)建SocketServer對(duì)象,該對(duì)象負(fù)責(zé)在服務(wù)
器端監(jiān)聽(tīng)客戶端請(qǐng)求。下面依次介紹構(gòu)造函數(shù)和使用方式。
(1)public void ServerSocket() throws IOException
該構(gòu)造函數(shù)創(chuàng)建一個(gè)不帶參數(shù)的默認(rèn)構(gòu)造方法。顯然該構(gòu)造函數(shù)不與任何
斷口綁定,這樣創(chuàng)建的對(duì)象無(wú)法直接調(diào)用accept()方法類監(jiān)聽(tīng)接入的訪問(wèn)
,必須綁定一個(gè)服務(wù)端口客戶端程序才可以訪問(wèn)到服務(wù)器程序。
(2)public ServerSocket(int port ) throws IOException
該構(gòu)造函數(shù)創(chuàng)建一個(gè)帶端口參數(shù)的ServerSocket對(duì)象,默認(rèn)的服務(wù)器地址
為本機(jī)的IP地址。
(3)public void ServerSocket(int port, int connectNumber) throws
IOExcepiton
該構(gòu)造函數(shù)有兩個(gè)參數(shù),第一個(gè)參數(shù)指定服務(wù)器的服務(wù)端口,第二個(gè)參數(shù)
指定服務(wù)器管理鏈接請(qǐng)求的的數(shù)量。
14.5.2? SocketServer類的兩個(gè)重要方法
SocketServer類的兩個(gè)重要方法如下所示。
(1)SocketServer 類accept()方法
當(dāng)客戶端向服務(wù)器發(fā)出請(qǐng)求時(shí),該請(qǐng)求保存在服務(wù)器主機(jī)操作系統(tǒng)維護(hù)的
請(qǐng)求隊(duì)列中,accept()方法負(fù)責(zé)從該請(qǐng)求隊(duì)列中取出一個(gè)最早的請(qǐng)求,該
方法返回一個(gè)Socket對(duì)象,服務(wù)器通過(guò)該對(duì)象實(shí)現(xiàn)與客戶端的雙向可靠通
信。
(2)SocketServer類close()方法
該方法關(guān)閉當(dāng)前服務(wù)器和客戶端的所有鏈接,釋放鏈接占用的資源如服務(wù)
端口,一般情況下不需要顯示的調(diào)用該方法,服務(wù)器程序退出時(shí),操作系
統(tǒng)回自動(dòng)釋放端口資源。顯示關(guān)閉SocketServer對(duì)象的方式如下所示。
ServerSocket serverSocket = New ServerSocket(8080);?
serverSocket.close();
14.5.3? 讀取SockerServer信息
ServerSocket類提供了一系列的get方法來(lái)獲得 ServerSocket的信息。如下
所示。
public InetAddress getInetAddress()
該方法返回建立了Socket鏈接的遠(yuǎn)端 Socket的地址,如果沒(méi)有建立鏈接則
返回null。
public InetAddress getLocalAddress()
該方法返回建立了Socket鏈接的本地地址。
public int getPort()
該方法返回建立了Socket鏈接的遠(yuǎn)端服務(wù)的端口號(hào)。
public int getLocalPort()
該方法返回建立了Socket鏈接的本地服務(wù)端口號(hào)。
14.5.3? 讀取SockerServer信息
publicInputStream getInputStream() throws IOException
該方法返回當(dāng)前Socket的輸入流。
publicOutputStream getOutputStream() throws IOException
該方法返回當(dāng)前Socket的輸入流。
其中常用的兩個(gè)方法如下所示:
Public InetAddress getInetAddress()
該方法返回該服務(wù)器綁定的IP地址,如果創(chuàng)建 ServerSocket對(duì)象時(shí)采用默
認(rèn)的地址,則是服務(wù)器的本地地址,如果在創(chuàng)建對(duì)象時(shí)顯示指定了服務(wù)器
地址,則getInetAddress()方法返回的是指定的地址。
Public int getLocalPort();
該方法返回服務(wù)端口,如果用戶沒(méi)有顯示設(shè)置該端口,則操作系統(tǒng)會(huì)隨即
分配一個(gè)端口,否則返回用戶指定的端口。
14.6? 數(shù)據(jù)報(bào)通信
在TCP/IP協(xié)議族中,UDP協(xié)議與TCP協(xié)議都是處在傳輸層。而UDP協(xié)議是一種
無(wú)鏈接協(xié)議,即在建立通信的雙方無(wú)須事先建立聯(lián)系,只要需要發(fā)送數(shù)據(jù)
只管發(fā)送,不需要考慮對(duì)方是否接受或網(wǎng)絡(luò)是否可靠。它發(fā)送的每個(gè)數(shù)據(jù)
報(bào)稱為UDP報(bào)文,稱為UDP數(shù)據(jù)報(bào)。每個(gè)數(shù)據(jù)報(bào)相互獨(dú)立,各自包含完整的
目的地地址,源地址和相應(yīng)的端口號(hào)。數(shù)據(jù)報(bào)在網(wǎng)絡(luò)的傳輸路徑取決于網(wǎng)
絡(luò)自身的狀況,至于能否到達(dá)目的地或到達(dá)后報(bào)文的正確性都難以保證。
在對(duì)方收到UDP報(bào)文后也不會(huì)作出任何反饋告訴發(fā)送方當(dāng)前的狀態(tài)。顯然這
種方式無(wú)法保證數(shù)據(jù)的正確性,也無(wú)法處理丟失報(bào)文的情況。
14.6.1? 數(shù)據(jù)報(bào)通信簡(jiǎn)介
基于Java的數(shù)據(jù)報(bào)通信主要依靠?jī)蓚€(gè)類來(lái)完成,一個(gè)是
java.net.DatagramSocket類,一個(gè)是java.net.DatagramPacket類。其中
DatagramPacket表示要發(fā)送或接受的數(shù)據(jù)報(bào),而DatagramSocket負(fù)責(zé)接收
和發(fā)送數(shù)據(jù)報(bào),如下代碼所示。
1 //創(chuàng)建一個(gè)數(shù)據(jù)報(bào)
2 DatagramPacket packet = new DatagramPacket(new byte
[1024],1024);
3 //等待接收數(shù)據(jù)報(bào), 如果沒(méi)有接收到數(shù)據(jù),進(jìn)程阻塞。
4? socket.receive(packet);
5 // 創(chuàng)建要發(fā)送的數(shù)據(jù)報(bào)
6 DatagramPacket Packet = new DatagramPacket(outputData,
7???????
outputData.length,remoteIP,8080);
8 //發(fā)出數(shù)據(jù)報(bào)
9 socket.send(Packet);
14.6.2? DatagramPacket類簡(jiǎn)介
(1)構(gòu)造函數(shù)
使用UDP協(xié)議發(fā)送和接收數(shù)據(jù),需要在程序中表示數(shù)據(jù)報(bào)以調(diào)用
DatagramSocket的receive()和send()方法來(lái)接收和發(fā)送數(shù)據(jù)報(bào),
DatagramPacket對(duì)象就是程序中的數(shù)據(jù)報(bào),該類通過(guò)構(gòu)造函數(shù)創(chuàng)建不同的
數(shù)據(jù)報(bào)。其構(gòu)造函數(shù)分為兩類,一類創(chuàng)建用于發(fā)送的數(shù)據(jù)報(bào),一類用于接
收的數(shù)據(jù)報(bào)。
(2)DatagramPacket類的連個(gè)重要方法
14.6.3? DatagramSocket類簡(jiǎn)介
DatagramSocket類負(fù)責(zé)接收和發(fā)送數(shù)據(jù)報(bào),每個(gè) DatagramSocket對(duì)象會(huì)綁
定一個(gè)服務(wù)端口,這個(gè)端口可以是顯示設(shè)置的,也可以采用匿名端口,匿
名端口由操作系統(tǒng)隨機(jī)分配。UDP數(shù)據(jù)報(bào)在兩個(gè)DatagramSocket的對(duì)象實(shí)體
間傳輸。
編寫數(shù)據(jù)報(bào)方式的客戶、服務(wù)器程序時(shí),首先需要在客戶方和服務(wù)器方建
立一個(gè)DatagramSocket對(duì)象,用來(lái)接收或發(fā)送數(shù)據(jù)報(bào)。接收和發(fā)送的數(shù)據(jù)
報(bào)由DatagramPacket類構(gòu)造。
14.6.4? 實(shí)現(xiàn)數(shù)據(jù)報(bào)通信
在學(xué)習(xí)過(guò)了數(shù)據(jù)報(bào)通信的機(jī)制,以及java.net.DatagramSocket類和
java.net.Datagram
類之后。我們通過(guò)一個(gè)具體里的基于UDP協(xié)議的客戶服務(wù)器程序說(shuō)明
DatagramSocket類來(lái)發(fā)送和接收數(shù)據(jù)的過(guò)程。
服務(wù)器程序的主機(jī)地址為本機(jī)地址,服務(wù)端口號(hào)為8080,程序啟動(dòng)后等待
接收數(shù)據(jù)而阻塞,直到接收到UDP數(shù)據(jù)報(bào)才終止阻塞狀態(tài)。接收到數(shù)據(jù)后,
顯示在控制臺(tái),并且把收到的數(shù)據(jù)再發(fā)送會(huì)客戶端。服務(wù)器程序如代碼所
示。
14.7? 本章習(xí)題
(1)學(xué)完本章中,讀者需要回答:
簡(jiǎn)述IP 協(xié)議的作用,ip協(xié)議工作在OSI參考模型的那一個(gè)層
TCP 協(xié)議的的作用?什么是一個(gè)網(wǎng)絡(luò)鏈接。
簡(jiǎn)述客戶/服務(wù)器通信模型。
如何通過(guò)Socket類創(chuàng)建客戶端程序
如何通過(guò) SocketServer類實(shí)現(xiàn)服務(wù)器端程序。
解釋什么是數(shù)據(jù)報(bào)通信。
如何通過(guò)DatagramPacket類創(chuàng)建數(shù)據(jù)報(bào)
如何通過(guò)DatagramSocket類實(shí)現(xiàn)數(shù)據(jù)報(bào)通信。
(2)注意事項(xiàng)。
1.本章的基本通信模型是C/S模型,在繼續(xù)學(xué)習(xí)客戶端/服務(wù)器應(yīng)用程序設(shè)
計(jì)前首先要理解該通信模型。
2.本章讀者一定要掌握最簡(jiǎn)單的通過(guò)Socket類SocketServer類實(shí)現(xiàn)客戶端
/服務(wù)器應(yīng)用程序的設(shè)計(jì)開(kāi)發(fā)。
3.掌握數(shù)據(jù)報(bào)通信的原理和具體實(shí)現(xiàn)方法。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
