Day15:網絡編程-Socket(UDP、TCP)

Java語言是一門Internet語言,遇過不能夠從Internet獲取數據,Java就是死的,所以網絡編程就是描述Java怎麼從Internet獲取數據!web

網絡要素:
IP: 地址<--解析-->主機名  InetAddress  getByName(hostname); getHostAddress  getHostName
端口:0-65535  
協議:
1、TCP(面向鏈接,可靠,效率稍低。)---客戶端:Socket  服務端ServerSocket  
2、UDP(面向無鏈接,不可靠,速度快)---發送端,接收端。DatagramSocket  ----  DatagramPacket(數據包)

在網絡編程中,最重要部分非Socket莫屬了,不管大小面試,對很是鍾愛與Socket,由於Socket是網絡通訊的基礎,是網絡通訊的最重要的工具面試

 

先用Socket實現UDP通訊編程

/*
 * 需求:創建UDP的發送端
 * 思路:
* 一、創建能夠實現UDP傳輸的socket服務
* 二、明確具體發送的數據
 * 三、經過socket服務將具體數據發送出去
* 四、關閉服務  
*/
//一、建立UDP服務
  try {
    DatagramSocket ds = new DatagramSocket();
    //二、明確數據
    String str = "注意啦,UDP要來啦!";
    //三、發送數據,將數據封裝到數據包中
    byte[] buf = str.getBytes();
    DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.137.1"), 9090); 
    ds.send(dp);
    //四、關閉服務
    ds.close();
    } catch (SocketException e) {
        // TODO Auto-generated catch block
        System.out.println("UDP服務發送端啓動失敗");
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        System.out.println("數據包發送失敗");
        e.printStackTrace();
    }
/*
 * 需求:創建UDP接收端
 * 思路:
* 一、建立socket服務,明確接受數據的端口
* 二、接受數據包
* 三、將接收到的數據包中的數據取出來,取出的數據包括IP、data、port
* 四、關閉服務
*/
    try {
    DatagramSocket ds = new DatagramSocket(9090);
    System.out.println("接收端啓動成功!");
    //三、接收數據包
    byte[] buf = new byte[1000];
    DatagramPacket dp = new DatagramPacket(buf, buf.length);        
    ds.receive(dp);//阻塞式方法,使得Receive類開啓時在等待狀態,直到接收到數據才結束
    //解析數據
    StringBuilder sb = new StringBuilder();
    sb.append("發送數據的IP爲:"+dp.getAddress().getHostAddress()+"\n");
    sb.append("接收到的數據爲:"+new String(dp.getData(),0,dp.getLength())+"\n");
    sb.append("接收數據端口爲:"+dp.getPort());
    System.out.println(sb.toString());
    //四、關閉服務
    ds.close();
    } catch (SocketException e) {
        // TODO Auto-generated catch block
        System.out.println("接收端啓動失敗!");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        System.out.println("數據包接收失敗!");
    }
//一個利用UDP協議寫的一個半實現的聊天室

public
class UDPChatRoom { /** * @param args * @throws SocketException */ public static void main(String[] args) throws SocketException { // TODO Auto-generated method stub /* * 需求:經過UDP協議完成一個聊天室程序(一個負責發送數據,另一個負責接收數據,兩個同時進行) */ //建立socket服務。 DatagramSocket send = new DatagramSocket(10086); DatagramSocket rece = new DatagramSocket(10010); new Thread(new Send(send)).start(); new Thread(new Receive(rece)).start(); } } // 負責發送的任務,經過UDPsocket發送。 class Send implements Runnable{ //創建數據包 private DatagramSocket ds; public Send(DatagramSocket ds){ super(); this.ds = ds; } @Override public void run() { // TODO Auto-generated method stub //一、創建能夠實現UDP傳輸的socket服務 //2讀取數據 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); String line = null; try { while((line = bufr.readLine())!=null){ if("over".equals(line)){ System.out.println(ds.getLocalSocketAddress()+":"+".....發送者離開聊天室"); } byte[] buf = line.getBytes(); DatagramPacket dp = new DatagramPacket(buf, buf.length,InetAddress.getByName("192.168.137.1"),10010); //3發送數據 ds.send(dp); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // 負責接收的任務 class Receive implements Runnable{ //創建數據包 private DatagramSocket ds; public Receive(DatagramSocket ds){ super(); this.ds = ds; } @Override public void run() { // TODO Auto-generated method stub while (true) { // 1,由於接收的數據最終都會存儲到數據包中。而數據包中必須有字節數組。 byte[] buf = new byte[1024]; // 2,建立數據包對象。 DatagramPacket dp = new DatagramPacket(buf, buf.length); // 3,將收到的數據存儲到數據包中。 try { ds.receive(dp); } catch (IOException e) { e.printStackTrace(); } // 4,獲取數據。 String ip = dp.getAddress().getHostAddress(); String data = new String(dp.getData(), 0, dp.getLength()); System.out.println(ip + ":" + data); if("over".equals(data)){ System.out.println(ip+".....接受者離開聊天室"); } } } }

再用Socket實現TCP通訊數組

 

/*
         * 需求:建立TCP服務端
         * 思路:
         * 一、建立Socket服務器端服務,服務端爲了能讓客戶端鏈接上,必須提供端口並監聽一個端口
         * 二、獲取客戶端對象,經過客戶端的Socket流和對應的客戶端進行通訊
         * 三、獲取客戶端的Socket流的讀取流
         * 四、讀取數據並顯示在服務器端
         * 五、關閉資源
         */
        //一、建立服務器端對象
        ServerSocket ss = new ServerSocket(10000);
        System.out.println("Server is Opening!");
        //二、獲取客戶端對象
        Socket s= ss.accept();
        String ip = s.getInetAddress().getHostAddress();
        //三、經過客戶端對象獲取Socket流的讀取
        InputStream in = s.getInputStream();
        
        byte[] buf = new byte[1024];
        int len = in.read(buf);
        String str = new String(buf,0,len);
        
        System.out.println(ip+":"+str);
        
        s.close();
        ss.close();

 

/*
         * 需求:TCP客戶端的創建
         * 思路:
         * 一、創建TCP客戶端服務
         *     1.1由於是面向鏈接,必需要有鏈接才能夠實現通訊
         *     1.2在建立客戶端的同時,就必須明確目的地址和端口
         * 二、一旦鏈接創建,就有了傳輸數據的通道,就能夠在通道中進行數據傳輸,數據的傳輸經過Socket-IO流實現
         * 三、只要獲取Socket-IO流中的寫動做就能夠進行發送數據到服務端
         * 四、釋放資源
         */
        //一、建立客戶端對象。明確目的地址和端口
        Socket s = new Socket("192.168.137.1",10000);
        System.out.println("Client is opening!");
        //二、獲取Socket流中的輸出流,將數據發送到服務端
        OutputStream os = s.getOutputStream();
        //三、經過輸出流寫數據
        os.write("注意啦,TCP要來啦!".getBytes());
        //四、釋放資源
        s.close();

要實現高級一點的東西了,要利用TCP設計一個半實現的聊天工具服務器

 

/*
         * 服務端收到客戶端的數據並反饋數據給客戶端。應答。
         */
        //1,建立服務端socket對象。
        ServerSocket ss = new ServerSocket(10004);
        System.out.println("ChatServer is Opening......");
        
        //2,獲取客戶端對象。
        Socket s = ss.accept();
        String ip = s.getInetAddress().getHostAddress();
        System.out.println(ip+".....connected");
        
        //3, 獲取socket讀取流。
        InputStream in = s.getInputStream();    
        byte[] buf = new byte[1024];
        int len = in.read(buf);
        String str = new String(buf,0,len);
        System.out.println(str);
            
        //4,給客戶端反饋數據。socket輸出流。
        OutputStream out = s.getOutputStream();
        out.write("哦了,我知道你來了".getBytes());
        
        //五、釋放資源
        s.close();
        ss.close();
//需求:客戶端發送數據給服務端,並讀取服務端反饋的數據。
        System.out.println("ChatClient is Opening.....");
        //1,建立socket客戶端。
        Socket s = new Socket("192.168.137.1",10004);
        
        //2,獲取socket輸出流。寫數據。
        OutputStream out = s.getOutputStream();
        out.write("服務端,我來了.".getBytes());
        
        //3,獲取socket的讀取流。讀取服務端發回的數據。
        InputStream in = s.getInputStream();
        byte[] buf = new byte[1024];
        int len = in.read(buf);
        String str = new String(buf,0,len);
        System.out.println(str);
        
        //四、釋放資源
        s.close();    

再高級一點,利用TCP協議進行傳送文件了(包括圖片、文本)網絡

 

    /*
         * 上傳文本的客戶端。讀取本地文本數據,發送給服務端,服務端接收完畢後,回饋"上傳成功"字樣。
         */
        //客戶端socket
        Socket s = new Socket("192.168.137.1",10005);
        System.out.println("上傳文本客戶端啓動......");

        //1,肯定數據源。本地文件文件
        BufferedReader bufr = new BufferedReader(new FileReader("client.txt"));

        //2,肯定目的IP和Socket-IO輸出流
        PrintWriter out = new PrintWriter(s.getOutputStream(),true);

        String line = null;
        while((line=bufr.readLine())!=null){
            out.println(line);
        }

        //使用socket的禁用輸出流方法來中止向服務端發送數據。
        s.shutdownOutput();

        //3,經過socket讀取流獲取服務端返回的數據。
        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String lineIn = bufIn.readLine();//阻塞式。
        System.out.println(lineIn);

        //4,釋放資源
        bufr.close();
        s.close();

 

/*
         * 上傳文本的服務端。接收文本數據,並存儲到文件中,服務端接收完畢後,回饋"上傳成功"字樣。
         */
        //1,服務端對象。
        ServerSocket ss = new ServerSocket(10005);
        System.out.println("上傳文本服務器端啓動.......");
        
        //2,獲取客戶端。
        Socket s = ss.accept();
        String ip = s.getInetAddress().getHostAddress();
        System.out.println(ip+".....connected");
        
        //3,獲取讀取流。肯定源,網絡socket。
        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
        
        //4,肯定目的文件。
        PrintWriter pw = new PrintWriter(new FileWriter("server.txt"),true);
        
        //5,頻繁讀寫。
        String line = null;
        while((line=bufIn.readLine())!=null){
            pw.println(line);
        }
        
        //6,給客戶端返回信息。
        PrintWriter out = new PrintWriter(s.getOutputStream(),true);
        out.println("上傳成功");
        
        //七、釋放資源
        pw.close();
        s.close();
        ss.close();

 

 

TCP的傳輸、上傳、問題:兩端等待的狀況。說明有阻塞式方法。沒有讀取到結束標記。shutdown. web原理:併發訪問,Server端:未來訪的客戶端都封裝到了一個單獨線程中。 ServerSocket server = new ServerSocket(10000); while(true) { Socket s = server.accept(); new Thread(new Task(s)).start(); }
相關文章
相關標籤/搜索