趙雅智_java網絡編程(1) – JAVA編程語言程序開發技術文章

—網絡基礎知識

|–InetAddress

—UDP

 

網絡基本概念

 

計算機網絡,就是把分佈在不同地理區域的計算機與專門的外部設備用通信線路互連成一個規模大、功能強的網絡系統,從而使眾多的計算機可以方便地互相傳遞信息,共享硬件、軟件、數據信息等資源。

 

網絡體系結構:

國際標準化組織ISO於l978年提出“開放系統互連參考模型”,即著名的OSI(Open System Interconnection)模型。

該模型把計算機網絡分成物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層、應用層等七層。

 

 

通信協議:

計算機網絡中實現通信必須有一些約定,即通信協議。對速率、傳輸代碼、代碼結構、傳輸控制步驟、出錯控制等制定標準。

TCP協議:提供可靠的數據傳輸服務的規則。

IP協議:進行IP數據包的分割和組裝。

但是通過IP協議並不能清楚地瞭解到數據包是否順利地發送給目標計算機。而使用TCP協議,它將數據包成功發送給目標計算機後,會要求發送一個確認,如果在某個時間內沒有收到確認,TCP將重新發送數據包。

TCP/IP協議:

 


 

IP地址和端口號

IP地址:為實現網絡中不同的計算機之間的通信,在網絡中的每臺機器都必須有一個與眾不同的標識,這就是IP地址(IP Address)。

                格式:數字型、32位、由4段8位的二進制數組成。一般表示為十進制形式(4個0~255的十進制整數),中間用圓點隔開,如:166.111.78.98。

                域名地址:也是分段表示的,便於記憶的、字符串形式。

端口:一個16位的整數,用於表示數據交給哪個通信程序處理。因此,端口就是應用程序與外界交流的出入口,它是一種抽象的軟件結構,包括一些數據結構和I/O(基本輸入/輸出)緩沖區。

不同的應用程序處理不同端口上的數據,同一臺機器上不能有兩個程序使用同一個端口,端口號可以從0到65535,通常將它分為三類:

公認端口(Well Known Ports):從0到1023,它們緊密綁定(Binding)一些服務。
註冊端口(Registered Ports):從1024到49151。它們松散地綁定一些服務。
動態和/或私有端口(Dynamicand/or Private Ports):從49152到65535,這些端口是應用程序使用的動態端口,應用程序一般不會主動使用這些端口。
 

InetAddress 類

JDK中為開發網絡應用程序提供瞭java.net包,該包下的類和接口幾乎都是為網絡編程服務的。

InetAddress:用於描述IP地址的對象

InetAddress類沒有提供構造方法,

而是提供瞭靜態方法來獲取InetAddress實例

getByName(String host):根據主機獲取對應的InetAddress對象。
getByAddress(byte[] addr):根據原始IP地址來獲取對應的InetAddress對象。
getAllByName(String host):返回數組

三個方法獲取InetAddress實例對應的IP地址和主機名

String getCanonicalHostName():此IP地址完全限定域名
String getHostName():實例對應的主機名
String getHostAddress():實例對應的IP地址
 

[java]
package net.csdn.web; 
 
import java.io.IOException; 
import java.net.InetAddress; 
 
public class Demo1 { 
 
    /**
     * @param args
     * @throws IOException 
     */ 
    public static void main(String[] args) throws IOException { 
        //根據主機名來獲取相應的InetAddress實例  
        InetAddress ia = InetAddress.getByName("192.168.49.50");         
        //判斷是否可達  
        System.out.println("oneedu是否可到達"+ia.isReachable(2000)); 
        //獲取該InetAddress實例的IP字符串  
        System.out.println(ia.getHostAddress()); 
        //獲取該InetAddress實例的IP字符串的主機名  
        System.out.println(ia.getHostName()); 
        //獲取該InetAddress實例的IP地址的完全限定域名  
        System.out.println(ia.getCanonicalHostName()); 
         
        //根據主機名來獲取相應的InetAddress實例數組  
        InetAddress[] ip = InetAddress.getAllByName(" "); 
        //遍歷數組  
        for(InetAddress i : ip){ 
            System.out.println(i.getHostAddress()+i.getHostName()); 
        } 
    } 

package net.csdn.web;

import java.io.IOException;
import java.net.InetAddress;

public class Demo1 {

 /**
  * @param args
  * @throws IOException
  */
 public static void main(String[] args) throws IOException {
        //根據主機名來獲取相應的InetAddress實例
        InetAddress ia = InetAddress.getByName("192.168.49.50");       
        //判斷是否可達
        System.out.println("oneedu是否可到達"+ia.isReachable(2000));
        //獲取該InetAddress實例的IP字符串
        System.out.println(ia.getHostAddress());
        //獲取該InetAddress實例的IP字符串的主機名
        System.out.println(ia.getHostName());
        //獲取該InetAddress實例的IP地址的完全限定域名
        System.out.println(ia.getCanonicalHostName());
       
        //根據主機名來獲取相應的InetAddress實例數組
        InetAddress[] ip = InetAddress.getAllByName("www.baidu.com");
        //遍歷數組
        for(InetAddress i : ip){
            System.out.println(i.getHostAddress()+i.getHostName());
        }
    }
}

 

 

 

UDP

什麼是UDP協議?

UDP( User Datagram Protocol )協議是用戶數據報,在網絡中它與TCP協議一樣用於處理數據包。在OSI模型中,在第四層——傳輸層,處於IP協議的上一層。

UDP是一種無連接的協議,每個數據報都是一個獨立的信息,包括完整的源或目的地址,它在網絡上以任何可能的路徑傳往目的地,因此能否到達目的地,到達目的地的時間以及內容的正確性都是不能被保證的。

文件<64k

為什麼要使用UDP?

在網絡質量令人不十分滿意的環境下,UDP協議數據包丟失會比較嚴重。但是由於UDP的特性:它不屬於連接型協議,因而具有資源消耗小,處理速度快的優點,所以通常音頻、視頻和普通數據在傳送時使用UDP較多,因為它們即使偶爾丟失一兩個數據包,也不會對接收結果產生太大影響。比如聊天用的ICQ和OICQ就是使用的UDP協議。

 

 

在Java中操縱UDP

使用位於JDK中Java.net包下的DatagramSocket和DatagramPacket類,可以非常方便地控制用戶數據報文。

DatagramSocket類:創建接收和發送UDP的Socket實例

DatagramSocket():創建實例。通常用於客戶端編程,它並沒有特定監聽的端口,僅僅使用一個臨時的。

DatagramSocket(int port):創建實例,並固定監聽Port端口的報文。

DatagramSocket(int port, InetAddresslocalAddr):這是個非常有用的構建器,當一臺機器擁有多於一個IP地址的時候,由它創建的實例僅僅接收來自LocalAddr的報文。

註意:在創建DatagramSocket類實例時,如果端口已經被使用,會產生一個SocketException的異常拋出,並導致程序非法終止,這個異常應該註意捕獲。

receive(DatagramPacket d):接收數據報文到`d中。receive方法產生一個“阻塞”。

                                                      “阻塞”是一個專業名詞,它會產生一個內部循環,使程序暫停在這個地方,直到一個條件觸發。

send(DatagramPacket d):發送報文d到目的地。

setSoTimeout(int timeout):設置超時時間,單位為毫秒。

close():關閉DatagramSocket。在應用程序退出的時候,通常會主動釋放資源,關閉Socket,但是由於異常地退出可能造成資源無法回收。所以,應該在程序完成時,主動使用此方法關閉Socket,或在捕獲到異常拋出後關閉Socket。

 

 

DatagramPacket:用於處理報文,將byte數組、目標地址、目標端口等數據包裝成報文或者將報文拆卸成byte數組。

DatagramPacket(byte[] buf, int length,InetAddress addr, int port):從buf數組中,取出length長的數據創建數據包對象,目標是addr地址,port端口。

DatagramPacket(byte[] buf, int offset, intlength, InetAddress address, int port):從buf數組中,取出offset開始的、length長的數據創建數據包對象,目標是addr地址,port端口。

DatagramPacket(byte[] buf, int offset, intlength):將數據包中從offset開始、length長的數據裝進buf數組。

DatagramPacket(byte[] buf, int length):將數據包中length長的數據裝進buf數組。

getData():它從實例中取得報文的byte數組編碼。

實例1,編寫程序演示使用UDP協議數據報的發送和接受。

發送端

[java]
package net.csdn.web; 
 
import java.io.IOException; 
import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.InetAddress; 
 
public class DemoSend { 
    public static void main(String[] args) throws IOException { 
        //1.建立udpsocket服務端點。該端點建立,系統會隨機分配一個端口。如果不想隨機配置,可以手動指定。  
        DatagramSocket ds = new DatagramSocket(); 
        //2.將數據進行packet包的封裝,必須要指定目的地地址和端口。  
        byte[] buf = "wo shi shu ju".getBytes(); 
        InetAddress is = InetAddress.getByName("192.168.49.50"); 
        DatagramPacket dp = new DatagramPacket(buf, buf.length,is,9009); 
        //3.通過socket服務的send方法將該包發出。  
        ds.send(dp); 
        //4.將socket服務關閉。主要是關閉資源。  
        ds.close(); 
    } 
 

package net.csdn.web;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class DemoSend {
 public static void main(String[] args) throws IOException {
  //1.建立udpsocket服務端點。該端點建立,系統會隨機分配一個端口。如果不想隨機配置,可以手動指定。
  DatagramSocket ds = new DatagramSocket();
  //2.將數據進行packet包的封裝,必須要指定目的地地址和端口。
  byte[] buf = "wo shi shu ju".getBytes();
  InetAddress is = InetAddress.getByName("192.168.49.50");
  DatagramPacket dp = new DatagramPacket(buf, buf.length,is,9009);
  //3.通過socket服務的send方法將該包發出。
  ds.send(dp);
  //4.將socket服務關閉。主要是關閉資源。
  ds.close();
 }

}

接收端

[java]
package net.csdn.web; 
 
import java.io.IOException; 
import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
 
public class DemoReceive { 
    public static void main(String[] args) throws IOException { 
        //1.建立udp的socket服務。要監聽一個端口。  
        DatagramSocket ds = new DatagramSocket(9009); 
        //2.定義一個緩沖區,將該緩沖區封裝到packet包中。  
        byte[] buf = new byte[1024]; 
        DatagramPacket dp = new DatagramPacket(buf, buf.length); 
         
        //3.通過socket的receive方法將數據存入數據包中。  
        ds.receive(dp); 
        //4.通過數據包dp的方法getData()、getAddress()、getPort()等方法獲取包中的指定信息。  
        String ip = dp.getAddress().getHostAddress(); 
        String data = new String(dp.getData(),0,dp.getLength()); 
        int port = dp.getPort(); 
        System.out.println(ip+":"+data+":"+port); 
        //5.關閉socket。  
        ds.close(); 
    } 
 

package net.csdn.web;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class DemoReceive {
 public static void main(String[] args) throws IOException {
  //1.建立udp的socket服務。要監聽一個端口。
  DatagramSocket ds = new DatagramSocket(9009);
  //2.定義一個緩沖區,將該緩沖區封裝到packet包中。
  byte[] buf = new byte[1024];
  DatagramPacket dp = new DatagramPacket(buf, buf.length);
  
  //3.通過socket的receive方法將數據存入數據包中。
  ds.receive(dp);
  //4.通過數據包dp的方法getData()、getAddress()、getPort()等方法獲取包中的指定信息。
  String ip = dp.getAddress().getHostAddress();
  String data = new String(dp.getData(),0,dp.getLength());
  int port = dp.getPort();
  System.out.println(ip+":"+data+":"+port);
  //5.關閉socket。
  ds.close();
 }

}

用cmd命令窗口打開:

 

 

實例2,編寫程序演示使用UDP協議數據報的發送和接受,可從鍵盤錄入

發送端

[java]
package net.csdn.web; 
 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.InetAddress; 
 
public class DemoSend2 { 
 
    /**
     * @param args
     */ 
    public static void main(String[] args) throws IOException { 
        // TODO Auto-generated method stub  
        DatagramSocket ds = new DatagramSocket(); 
         
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
        String line = null; 
        while((line = br.readLine()) != null){ 
            if(line.equals(888)){ 
                break; 
            } 
            byte[] buf = line.getBytes(); 
            DatagramPacket dp = new DatagramPacket(buf, buf.length,InetAddress.getByName("192.168.49.255"),9009); 
            ds.send(dp); 
        } 
        ds.close(); 
    } 

package net.csdn.web;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class DemoSend2 {

 /**
  * @param args
  */
 public static void main(String[] args) throws IOException {
  // TODO Auto-generated method stub
  DatagramSocket ds = new DatagramSocket();
  
  BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  String line = null;
  while((line = br.readLine()) != null){
   if(line.equals(888)){
    break;
   }
   byte[] buf = line.getBytes();
   DatagramPacket dp = new DatagramPacket(buf, buf.length,InetAddress.getByName("192.168.49.255"),9009);
   ds.send(dp);
  }
  ds.close();
 }
}
接收端

[java]
package net.csdn.web; 
 
import java.io.IOException; 
import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
 
public class DemoReceive2 { 
 
    public static void main(String[] args) throws IOException { 
        // TODO Auto-generated method stub  
        DatagramSocket ds = new DatagramSocket(9009); 
         
        while(true){ 
            byte[] buf = new byte[1024]; 
            DatagramPacket dp = new DatagramPacket(buf, buf.length); 
             
            ds.receive(dp); 
             
            String ip = dp.getAddress().getHostAddress(); 
            String data = new String(dp.getData(),0,dp.getLength()); 
            System.out.println(ip+":"+data); 
        } 
    } 
     

package net.csdn.web;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class DemoReceive2 {

 public static void main(String[] args) throws IOException {
  // TODO Auto-generated method stub
  DatagramSocket ds = new DatagramSocket(9009);
  
  while(true){
   byte[] buf = new byte[1024];
   DatagramPacket dp = new DatagramPacket(buf, buf.length);
   
   ds.receive(dp);
   
   String ip = dp.getAddress().getHostAddress();
   String data = new String(dp.getData(),0,dp.getLength());
   System.out.println(ip+":"+data);
  }
 }
 
}

 


 

對話框,在同一區域進行收發

[java] view plaincopyprint?package src.com.hbsi.net; 
import java.net.*; 
import java.io.*; 
 
public class ChatDemo { 
 
    /**
     * @param args
     */ 
    public static void main(String[] args) { 
        try { 
            DatagramSocket send=new DatagramSocket(); 
            DatagramSocket rece=new DatagramSocket(9008); 
             
            new Thread(new ChatSend(send)).start(); 
            new Thread(new ChatRece(rece)).start(); 
             
        } catch (SocketException e) { 
            // TODO Auto-generated catch block  
            e.printStackTrace(); 
        } 
 
    } 
 

 
class ChatSend implements Runnable{ 
    DatagramSocket ds; 
     
    public ChatSend(DatagramSocket ds){ 
        this.ds=ds; 
    } 
     
    @Override 
    public void run() { 
        try{ 
            BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 
         
            String line=null; 
             
            while((line=br.readLine())!=null){ 
                if(line.equals("over")) 
                    break; 
                 
                byte[] buf=line.getBytes(); 
                 
                DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.49.255"),9008); 
                 
                ds.send(dp); 
            } 
            ds.close(); 
        }catch(Exception e){ 
            e.printStackTrace(); 
        }    
    } 
     

 
class ChatRece implements Runnable{ 
     DatagramSocket ds; 
         
     public ChatRece(DatagramSocket ds){ 
            this.ds=ds; 
       } 
    @Override 
    public void run() { 
        while(true){ 
            try{ 
                byte[] buf=new byte[1024]; 
                 
                DatagramPacket dp=new DatagramPacket(buf,buf.length); 
                 
                ds.receive(dp); 
                 
                String ip=dp.getAddress().getHostAddress(); 
                 
                String data=new String(dp.getData(),0,dp.getLength()); 
                 
                System.out.println(ip+":"+data); 
                 
                 
            }catch(Exception e){ 
                e.printStackTrace(); 
            } 
        } 
         
    } 
     

package src.com.hbsi.net;
import java.net.*;
import java.io.*;

public class ChatDemo {

 /**
  * @param args
  */
 public static void main(String[] args) {
  try {
   DatagramSocket send=new DatagramSocket();
   DatagramSocket rece=new DatagramSocket(9008);
   
   new Thread(new ChatSend(send)).start();
   new Thread(new ChatRece(rece)).start();
   
  } catch (SocketException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }

}

class ChatSend implements Runnable{
    DatagramSocket ds;
   
    public ChatSend(DatagramSocket ds){
     this.ds=ds;
    }
   
 @Override
 public void run() {
  try{
   BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
  
   String line=null;
   
   while((line=br.readLine())!=null){
    if(line.equals("over"))
     break;
    
    byte[] buf=line.getBytes();
    
    DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.49.255"),9008);
    
    ds.send(dp);
   }
   ds.close();
  }catch(Exception e){
   e.printStackTrace();
  } 
 }
 
}

class ChatRece implements Runnable{
  DatagramSocket ds;
    
  public ChatRece(DatagramSocket ds){
      this.ds=ds;
    }
 @Override
 public void run() {
  while(true){
   try{
    byte[] buf=new byte[1024];
    
    DatagramPacket dp=new DatagramPacket(buf,buf.length);
    
    ds.receive(dp);
    
    String ip=dp.getAddress().getHostAddress();
    
    String data=new String(dp.getData(),0,dp.getLength());
    
    System.out.println(ip+":"+data);
    
    
   }catch(Exception e){
    e.printStackTrace();
   }
  }
  
 }
 
}

 

 

發佈留言