1. 程式人生 > >Java程式設計師從笨鳥到菜鳥之(十四)Html基礎總結(上)

Java程式設計師從笨鳥到菜鳥之(十四)Html基礎總結(上)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

 本文來自:曹勝歡部落格專欄。轉載請註明出處:http://blog.csdn.net/csh624366188

 

       首先宣告一下,剛開始學習java網路通訊程式設計

就對他有一種畏懼感,因為自己對網路一竅不通,所以。。。呵呵。。你懂得,昨天又仔細的學習了一遍,感覺其實java網路程式設計也沒想象的那麼難,不信,咱一起看看。。。呵呵。。

     網路程式設計就是在兩個或兩個以上的裝置(例如計算機)之間傳輸資料。程式設計師所作的事情就是把資料傳送到指定的位置,或者接收到指定的資料,這個就是狹義的網路程式設計範疇。在傳送和接收資料時,大部分的程式設計語言都設計了專門的API實現這些功能,程式設計師只需要呼叫即可。所以,基礎的網路程式設計可以和打電話一樣簡單

一:首先看一下網路通訊的兩種方式

1.TCP(傳輸控制協議)方式

TCP方式就類似於撥打電話,使用該種方式進行網路通訊時,需要建立專門的虛擬連線,然後進行可靠的資料傳輸,如果資料傳送失敗,則客戶端會自動重發該資料

2. UDP(使用者資料報協議)方式

     UDP方式就類似於傳送簡訊,使用這種方式進行網路通訊時,不需要建立專門的虛擬連線,傳輸也不是很可靠,如果傳送失敗則客戶端無法獲得

 這兩種傳輸方式都是實際的網路程式設計中進行使用,重要的資料一般使用TCP方式進行資料傳輸,而大量的非核心資料則都通過UDP方式進行傳遞,在一些程式中甚至結合使用這兩種方式進行資料的傳遞。由於TCP需要建立專用的虛擬連線以及確認傳輸是否正確,所以使用TCP方式的速度稍微慢一些,而且傳輸時產生的資料量要比UDP稍微大一些。

總結一下UDPTCP協議的區別

-使用UDP時,每個資料報中都給出了完整的地址資訊,因此無需要建立傳送方和接收方的連線。 

–對於TCP協議,由於它是一個面向連線的協議,在socket之間進行資料傳輸之前必然要建立連線,所以在TCP中多了一個連線建立的時間 

–使用UDP傳輸資料時是有大小限制的,每個被傳輸的資料報必須限定在64KB之內。 

–TCP沒有這方面的限制,一旦連線建立起來,雙方的socket就可以按統一的格式傳輸大量的資料。 

–UDP是一個不可靠的協議,傳送方所傳送的資料報並不一定以相同的次序到達接收方。 

–TCP是一個可靠的協議,它確保接收方完全正確地獲取傳送方所傳送的全部資料 

-TCP在網路通訊上有極強的生命力,例如遠端連線(Telnet)和檔案傳輸(FTP)都需要不定長度的資料被可靠地傳輸。 

—相比之下UDP操作簡單,而且僅需要較少的監護,因此通常用於區域網高可靠性的分散系統中client/server應用程式 

二:基於url的網路程式設計

1.建立一個URL

為了表示URL, java.net中實現了類URL。我們可以通過下面的構造方法來初始化一個URL物件:
  
(1) public URL (String spec);
     通過一個表示URL地址的字串可以構造一個URL物件
     URL urlBase=new URL("http://www. 263.net/")
   (2) public URL(URL context, String spec);
     通過基URL和相對URL構造一個URL物件。
     URL net263=new URL ("http://www.263.net/");
     URL index263=new URL(net263, "index.html")
  (3) public URL(String protocol, String host, String file);
     new URL("http", "www.gamelan.com", "/pages/Gamelan.net. html");
  (4) public URL(String protocol, String host, int port, String file);
     URL gamelan=new URL("http", "www.gamelan.com", 80, "Pages/Gamelan.network.html");

  注意:類URL的構造方法都宣告拋棄非執行時例外(MalformedURLException),因此生成URL物件時,我們必須要對這一例外進行處理,通常是用try-catch語句進行捕獲。格式如下:

try{
     URL myURL= new URL()
  }catch (MalformedURLException e){
  …  }

2. 解析一個URL

一個URL物件生成後,其屬性是不能被改變的,但是我們可以通過類URL所提供的方法來獲取這些屬性:
   public String getProtocol() 獲取該URL的協議名。
   public String getHost() 獲取該URL的主機名。
   public int getPort() 獲取該URL的埠號,如果沒有設定埠,返回-1。
   public String getFile() 獲取該URL的檔名。
   public String getRef() 獲取該URL在檔案中的相對位置。
   public String getQuery() 獲取該URL的查詢資訊。
   public String getPath() 獲取該URL的路徑
    public String getAuthority() 獲取該URL的許可權資訊
   public String getUserInfo() 獲得使用者的資訊
    public String getRef()獲得該URL的錨

3.從URL讀取WWW網路資源

當我們得到一個URL物件後,就可以通過它讀取指定的WWW資源。這時我們將使用URL的方法openStream(),其定義為:
InputStream openStream();
  
  方法openSteam()與指定的URL建立連線並返回InputStream類的物件以從這一連線中讀取資料。
URL url = new URL("http://www.baidu.com");

//使用openStream得到一輸入流並由此構造一個BufferedReader物件

BufferedReader br = new BufferedReader(new InputStreamReader( url.openStream()));

String line = null;

while(null != (line = br.readLine()))

{

System.out.println(line);

}

br.close();

三:客戶端網路程式設計步驟

按照前面的基礎知識介紹,無論使用TCP方式還是UDP方式進行網路通訊,網路程式設計都是由客戶端和伺服器端組成

1.客戶端網路程式設計步驟

        客戶端(Client)是指網路程式設計中首先發起連線的程式,客戶端一般實現程式介面和基本邏輯實現,在進行實際的客戶端程式設計時,無論客戶端複雜還是簡單,以及客戶端實現的方式,客戶端的程式設計主要由三個步驟實現:

1、 建立網路連線

客戶端網路程式設計的第一步都是建立網路連線。在建立網路連線時需要指定連線到的伺服器的IP地址和埠號,建立完成以後,會形成一條虛擬的連線,後續的操作就可以通過該連線實現資料交換了。

2、 交換資料

連線建立以後,就可以通過這個連線交換資料了。交換資料嚴格按照請求響應模型進行,由客戶端傳送一個請求資料到伺服器,伺服器反饋一個響應資料給客戶端,如果客戶端不傳送請求則伺服器端就不響應。

根據邏輯需要,可以多次交換資料,但是還是必須遵循請求響應模型。

3、 關閉網路連線

在資料交換完成以後,關閉網路連線,釋放程式佔用的埠、記憶體等系統資源,結束網路程式設計。

        最基本的步驟一般都是這三個步驟,在實際實現時,步驟2會出現重複,在進行程式碼組織時,由於網路程式設計是比較耗時的操作,所以一般開啟專門的現場進行網路通訊。

2.伺服器端網路程式設計步驟

        伺服器端(Server)是指在網路程式設計中被動等待連線的程式,伺服器端一般實現程式的核心邏輯以及資料儲存等核心功能。伺服器端的程式設計步驟和客戶端不同,是由四個步驟實現,依次是:

1、 監聽埠

伺服器端屬於被動等待連線,所以伺服器端啟動以後,不需要發起連線,而只需要監聽本地計算機的某個固定埠即可。

這個埠就是伺服器端開放給客戶端的埠,伺服器端程式執行的本地計算機的IP地址就是伺服器端程式的IP地址。

2、 獲得連線

當客戶端連線到伺服器端時,伺服器端就可以獲得一個連線,這個連線包含客戶端的資訊,例如客戶端IP地址等等,伺服器端和客戶端也通過該連線進行資料交換。

一般在伺服器端程式設計中,當獲得連線時,需要開啟專門的執行緒處理該連線,每個連線都由獨立的執行緒實現。

3、 交換資料

伺服器端通過獲得的連線進行資料交換。伺服器端的資料交換步驟是首先接收客戶端傳送過來的資料,然後進行邏輯處理,再把處理以後的結果資料傳送給客戶端。簡單來說,就是先接收再發送,這個和客戶端的資料交換數序不同。

其實,伺服器端獲得的連線和客戶端連線是一樣的,只是資料交換的步驟不同。

當然,伺服器端的資料交換也是可以多次進行的。

在資料交換完成以後,關閉和客戶端的連線。

4、 關閉連線

當伺服器程式關閉時,需要關閉伺服器端,通過關閉伺服器端使得伺服器監聽的埠以及佔用的記憶體可以釋放出來,實現了連線的關閉。

四:一個基礎的網路類——InetAddress類

    該類的功能是代表一個IP地址,並且將IP地址和域名相關的操作方法包含在該類的內部。

    關於該類的使用,下面通過一個基礎的程式碼示例演示該類的使用,程式碼如下:

public class InetAddressDemo {public static void main(String[] args) {try {// 使用域名建立物件InetAddress inet1 = InetAddress.getByName("www.163.com");System.out.println(inet1);// 使用IP建立物件InetAddress inet2 = InetAddress.getByName("127.0.0.1");System.out.println(inet2);// 獲得本機地址物件InetAddress inet3 = InetAddress.getLocalHost();System.out.println(inet3);// 獲得物件中儲存的域名String host = inet3.getHostName();System.out.println("域名:" + host);// 獲得物件中儲存的IPString ip = inet3.getHostAddress();System.out.println("IP:" + ip);} catch (Exception e) {}}}  

注:InetAddress 類沒有明顯的建構函式。為生成一個InetAddress物件,必須運用一個可用的工廠方法。 

–工廠方法(factory method)僅是一個類中靜態方法返回一個該類例項的約定。對於InetAddress,三個方法 getLocalHost( )、getByName( )以及getAllByName( )可以用來建立InetAddress的例項 

•如果這些方法不能解析主機名,它們引發一個UnknownHostException異常。 

五:TCP程式設計

在Java語言中,對於TCP方式的網路程式設計提供了良好的支援,在實際實現時,以java.net.Socket類代表客戶端連線,以java.net.ServerSocket類代表伺服器端連線。在進行網路程式設計時,底層網路通訊的細節已經實現了比較高的封裝,所以在程式設計師實際程式設計時,只需要指定IP地址和埠號碼就可以建立連線了。

在客戶端網路程式設計中,首先需要建立連線,在Java API中以java.net.Socket類的物件代表網路連線

客戶端

1) 建立Socket連線 

Socket socket2 = new Socket(www.sohu.com,80);

2)按照“請求-響應”模型進行網路資料交換

在Java語言中,資料傳輸功能由Java IO實現,也就是說只需要從連線中獲得輸入流和輸出流即可,然後將需要傳送的資料寫入連線物件的輸出流中,在傳送完成以後從輸入流中讀取資料即可。示例程式碼如下:

 OutputStream os = socket1.getOutputStream(); //獲得輸出流

 InputStream is = socket1.getInputStream();     //獲得輸入流

這裡獲得的只是最基本的輸出流和輸入流物件,還可以根據前面學習到的IO知識,使用流的巢狀將這些獲得到的基本流物件轉換成需要的裝飾流物件,從而方便資料的操作。

3關閉網路連線

 socket1.close();

伺服器端

首先需要說明的是,客戶端的步驟和伺服器端的編寫步驟不同,所以在學習伺服器端程式設計時注意不要和客戶端混淆起來。

1)監聽埠

ServerSocket ss = new ServerSocket(10000);

2)獲得連線

當有客戶端連線到達時,建立一個和客戶端連線對應的Socket連 接物件,從而釋放客戶端連線對於伺服器端埠的佔用

Socket socket = ss.accept();

該程式碼實現的功能是獲得當前連線到伺服器端的客戶端連線。需要說明的是accept和前面IO部分介紹的read方法一樣,都是一個阻塞方法,也就是當無連線時,該方法將阻塞程式的執行,直到連線到達時才執行該行程式碼。另外獲得的連線會在伺服器端的該埠註冊,這樣以後就可以通過在伺服器端的註冊資訊直接通訊,而註冊以後伺服器端的埠就被釋放出來,又可以繼續接受其它的連線了。

3)按照“請求-響應”模型進行網路資料交換

這裡獲得的Socket型別的連線就和客戶端的網路連線一樣了,只是伺服器端需要首先讀取傳送過來的資料,然後進行邏輯處理以後再發送給客戶端,也就是交換資料的順序和客戶端交換資料的步驟剛好相反

 InputStream is = ss.getInputStream();     //獲得輸入流

OutputStream os = ss.getOutputStream(); //獲得輸出流

4)關閉伺服器端連線

ss.close();

以上就是基本的TCP型別的伺服器和客戶端程式碼實現的步驟,下面以一個簡單的echo(回聲)服務實現為例子,介紹綜合使用示例,實現的程式碼如下:

public class Constants public static void main(String[] args) {  ServerSocket serverSocket = null;  Socket socket = null;  OutputStream os = null;  InputStream is = null;  // 監聽埠號  int port = 10000;  try {   // 建立連線  serverSocket = new ServerSocket(port);   // 獲得連線   socket = serverSocket.accept();   // 接收客戶端傳送內容   is = socket.getInputStream();   byte[] b = new byte[1024];   int n = is.read(b);   // 輸出   System.out.println("客戶端傳送內容為:" + new String(b, 0, n));   // 向客戶端傳送反饋內容   os = socket.getOutputStream();   os.write(b, 0, n);  } catch (Exception e) {  e.printStackTrace();  } finally {   try {    // 關閉流和連線    os.close();    is.close();    socket.close();    serverSocket.close();   } catch (Exception e) {   }  } }}

UDP程式設計

     UDP(User Datagram Protocol),中文意思是使用者資料報協議使用該種方式無需建立專用的虛擬連線,由於無需建立專用的連線,所以對於伺服器的壓力要比TCP小很多,所以也是一種常見的網路程式設計方式。但是使用該種方式最大的不足是傳輸不可靠,當然也不是說經常丟失,就像大家發簡訊息一樣,理論上存在收不到的可能

     在Java API中,實現UDP方式的程式設計,包含客戶端網路程式設計和伺服器端網路程式設計,主要由兩個類實現,分別是:

l DatagramSocket

DatagramSocket類實現“網路連線”,包括客戶端網路連線和伺服器端網路連線。雖然UDP方式的網路通訊不需要建立專用的網路連線,但是畢竟還是需要傳送和接收資料,DatagramSocket實現的就是傳送資料時的發射器,以及接收資料時的監聽器的角色。類比於TCP中的網路連線,該類既可以用於實現客戶端連線,也可以用於實現伺服器端連線。

l DatagramPacket

DatagramPacket類實現對於網路中傳輸的資料封裝,也就是說,該類的物件代表網路中交換的資料。在UDP方式的網路程式設計中,無論是需要傳送的資料還是需要接收的資料,都必須被處理成DatagramPacket型別的物件,該物件中包含傳送到的地址、傳送到的埠號以及傳送的內容等。其實DatagramPacket類的作用類似於現實中的信件,在信件中包含信件傳送到的地址以及接收人,還有傳送的內容等,郵局只需要按照地址傳遞即可。在接收資料時,接收到的資料也必須被處理成DatagramPacket型別的物件,在該物件中包含傳送方的地址、埠號等資訊,也包含資料的內容。和TCP方式的網路傳輸相比,IO程式設計在UDP方式的網路程式設計中變得不是必須的內容,結構也要比TCP方式的網路程式設計簡單一些。

UDP客戶端程式設計涉及的步驟也是4個部分:建立連線、傳送資料、接收資料和關閉連線。

1)建立連線:

DatagramSocket ds = new DatagramSocket();

該客戶端連線使用系統隨機分配的一個本地計算機的未用埠號

 當然,可以通過制定連線使用的埠號來建立客戶端連線。

  DatagramSocket ds = new DatagramSocket(5000);

一般在建立客戶端連線時沒有必要指定埠號碼。

2)傳送資料

在傳送資料時,需要將需要傳送的資料內容首先轉換為byte陣列,然後將資料內容、伺服器IP和伺服器埠號一起構造成一個DatagramPacket型別的物件,這樣資料的準備就完成了了,傳送時呼叫網路連線物件中的send方法傳送該物件即可

程式碼示例:

   String s = "Hello";    String host = "127.0.0.1";    int port = 10001;   //將傳送的內容轉換為byte陣列    byte[] b = s.getBytes();    //將伺服器IP轉換為InetAddress物件    InetAddress server = InetAddress.getByName(host);    //構造傳送的資料包物件    DatagramPacket sendDp = new DatagramPacket(b,b.length,server,port);    //傳送資料    ds.send(sendDp);


 

      在該示例程式碼中,不管傳送的資料內容是什麼,都需要轉換為byte陣列,然後將伺服器端的IP地址構造成InetAddress型別的物件,在準備完成以後,將這些資訊構造成一個DatagramPacket型別的物件,在UDP程式設計中,傳送的資料內容、伺服器端的IP和埠號,都包含在DatagramPacket物件中。在準備完成以後,呼叫連線物件ds的send方法把DatagramPacket物件傳送出去即可。

3)UDP客戶端程式設計中接收資料

     首先構造一個數據緩衝陣列,該陣列用於儲存接收的伺服器端反饋資料,該陣列的長度必須大於或等於伺服器端反饋的實際有效資料的長度。然後以該緩衝陣列為基礎構造一個DatagramPacket資料包物件,最後呼叫連線物件的receive方法接收資料即可。接收到的伺服器端反饋資料儲存在DatagramPacket型別的物件內部

示例程式碼:

   //構造緩衝陣列    byte[] data = new byte[1024];    //構造資料包物件    DatagramPacket receiveDp = new DatagramPacket(data,data.length);    //接收資料    ds.receive(receiveDp);    //輸出資料內容    byte[] b = receiveDp.getData(); //獲得緩衝陣列    int len = receiveDp.getLength(); //獲得有效資料長度    String s = new String(b,0,len);    System.out.println(s);


 

程式碼講解 :  首先構造緩衝陣列data,這裡設定的長度1024是預估的接收到的資料長度,要求該長度必須大於或等於接收到的資料長度,然後以該緩衝陣列為基礎,構造資料包物件,使用連線物件ds的receive方法接收反饋資料,由於在Java語言中,除String以外的其它物件都是按照地址傳遞,所以在receive方法內部可以改變資料包物件receiveDp的內容,這裡的receiveDp的功能和返回值類似。資料接收到以後,只需要從資料包物件中讀取出來就可以了,使用DatagramPacket物件中的getData方法可以獲得資料包物件的緩衝區陣列,但是緩衝區陣列的長度一般大於有效資料的長度,換句話說,也就是緩衝區陣列中只有一部分資料是反饋資料,所以需要使用DatagramPacket物件中的getLength方法獲得有效資料的長度,則有效資料就是緩衝陣列中的前有效資料長度個內容,這些才是真正的伺服器端反饋的資料的內容

4)關閉連線

  ds.close();

UDP方式伺服器端網路程式設計

1)首先UDP方式伺服器端網路程式設計需要建立一個連線,該連線監聽某個埠:

 DatagramSocket ds = new DatagramSocket(10010);

由於伺服器端的埠需要固定,所以一般在建立伺服器端連線時,都指定埠號

2)接收客戶端傳送過來的資料

其接收的方法和客戶端接收的方法一直,其中receive方法的作用類似於TCP方式中accept方法的作用,該方法也是一個阻塞方法,其作用是接收資料。

ds.receive()

接收到客戶端傳送過來的資料以後,伺服器端對該資料進行邏輯處理,然後將處理以後的結果再發送給客戶端,在這裡傳送時就比客戶端要麻煩一些,因為伺服器端需要獲得客戶端的IP和客戶端使用的埠號,這個都可以從接收到的資料包中獲得。示例程式碼如下:

     //獲得客戶端的IP

     InetAddress clientIP = receiveDp.getAddress();

         //獲得客戶端的埠號

         Int clientPort = receiveDp.getPort();

3)關閉連線

ds.close()

        好了,佔時就總結到這吧,總結的不是很全面,但很基礎,應該適合初學者學習,由於本人也是初學者的小菜鳥,所有很多東西可能都涉及不到,希望大家見諒!

 

 本文來自:曹勝歡部落格專欄。轉載請註明出處:http://blog.csdn.net/csh624366188

 

推薦積累下一篇: Java程式設計師從笨鳥到菜鳥之(十四)Html基礎總結(上)            

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述