二十三、Java基礎--------網絡編程

        Java中另一個重要技術就是網絡編程了,爲了更好的學習web方向的知識,有必要對java之網絡編程好好學習,本文將圍繞網絡編程技術進行分析。

常見的網絡協議:UDP、TCP

UDP

       1、 將數據源和目的封裝爲數據包,不需要建立連接

        2、每個數據包大小在64K內

        3、因爲面向無連接,所以不可靠(丟失數據)

        4、不需要連接,速度快

        常見的UDP:聊天、視頻會議、桌面共享等等

TCP

       1、 建立連接,形成傳輸數據的通道

        2、在連接中進行大量數據的傳輸

        3、通過三次握手完成連接,是可靠協議

        4、必須建立連接,效率會相對較低

Socket

    Socket就是爲網絡服務的一種機制,通信兩段都有socket,網絡通信其實就是socket間的通信。數據自練個socket間通過IO傳輸。

UDP建立連接步驟

    需求:通過UDP傳輸方式,將一段文字發送出去,另一端進行接受並打印

    思路:

    發送端:

                1、建立UDP socket服務

                2、提供數據,將數據封裝到數據包中

                3、通過socket服務,將數據包發送出去

                4、關閉資源

    接受端:

                1、定義UDP socket服務,通常會監聽一個端口,方便與明確該應用程序處理的對象。

                2、定義一個數據包,以便於存儲接收到數據,數據包對象中提供了更多操作接收數據處理的方法

                3、通過socket服務的receive方法,將接收到的數據包存於已定義的數據包中。

                4、通過數據對象特有的功能將這些不同的數據取出,並進行後續的處理

                5、關閉資源

具體步驟:

    發送端:

        1、創建UDP服務,通過DatagramSocket對象

            DatagramSocket ds =new DatagramSocket();

        2、確定數據並封裝成數據包

            DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAdress,port)

        3、通過socket服務,將已經封包的數據進行發送

           ds.senf(dp)

        4、關閉資源

           ds.close();

    接收端:

                1、創建UDP socket,建立端點(指明監聽的端口)

                    DatagramSocket ds =new DatagramSocket(100010);

               2、 定義數據包用於存儲接受進來的數據

                     Byte []by=new byte[1024];

          DatagramPacket dp=new DatagramPacket(by,by.length);

                3、通過服務的receive方法接受數據,並存於到已定義的數據包中

                   ds.receive(dp);

                4、通過數據包的特有方法去除取出其中的數據

                   String s=new String(dp.getData());

                5、關閉資源

                   ds.close();

TCP建立連接步驟

    需求:建立TCP鏈接,並傳輸一段數據到服務器,服務器接收數據並打印該數據

    客戶端

               1、 建立服務端點,指明主機名以及端口號

                     Socket s=new Socket("127.0.0.1",10010);

                2、讀取客戶端要傳送的數據

                    byte []by="TCP I am coming".getBytes();

                3、通過socket輸出流將數據發給服務器

                    OutputStream out=s.getOutputStream();

                    out.wirte(by);

                5、關閉資源

                   s.close();

    服務端:

               1、 建立服務端並指明監聽端口

                    ServerSocket ss=new ServerSocker=t(10010);

                2、開啓服務,並接受數據

                    Scoket s=ss.accept();

                3、讀取接受到的數據,並封裝成包(本例只是打印)

                     InputStream in=s.getInputStream();

                     int len=0;

                     byte by[]=new byte[1024];

                    len=in.read(by);

                    System.out.println(new String(by,0,len));

                4、關閉資源

                    s.close();

案例分析:

    需求:編寫一個UDP聊天程序:
            分析:
                有接受數據的部分,和發數據的部分,這兩部分需要同時執行,這就需要用到多線程了

     發送端:

/*
 * 編寫一個聊天程序:
 * 分析:
 *         有接受數據的部分,和發數據的部分,這兩部分需要同時執行,這就需要用到多線程了
 * */
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;
/*
 * 發送端
 *     
 * */
public class UDP_Send_03 implements Runnable{
    private DatagramSocket ds;
    UDP_Send_03(DatagramSocket ds){
        this.ds=ds;
    }
    public void run() {
        try {
            ds=new DatagramSocket();
            Scanner sc=new Scanner(System.in);
            String line;
            while((line=sc.nextLine())!=null){
                if("886".equals(line))
                    break;
                byte by[]=line.getBytes();
                DatagramPacket dp=new DatagramPacket(by,by.length,InetAddress.getByName("127.0.0.1"),10110);
                ds.send(dp);
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
}

接收端:

import java.io.IOException;
import java.net.*;

/*
 * 編寫一個聊天程序:
 * 
 * 接受端
 * */
public class UDP_Rec_03 implements Runnable {
    private DatagramSocket ds;
    UDP_Rec_03(DatagramSocket ds){
        this.ds=ds;
    }
    public void run() {
        try {
            ds=new DatagramSocket(10110);
            
            while(true){
            byte by[]=new byte[1024];
            
            DatagramPacket  dp=new DatagramPacket(by,by.length);
            ds.receive(dp);
            String data=new String(dp.getData(),0,dp.getLength());
            
            System.out.println(data);
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }
    //通過多線程的方式同時開啓兩個服務,這樣就可以模擬聊天軟件的環境進行交流了
    public static void main(String[] args) throws SocketException {
        DatagramSocket ds=new DatagramSocket();
        UDP_Rec_03 rec=new UDP_Rec_03(ds);
        UDP_Send_03 send=new UDP_Send_03(ds);
        new Thread(rec).start();
        new Thread(send).start();
                
    }
}

案例2:編寫一個基於TCP的程序,完成客戶端向服務器發送一段文字,服務器接收到後返回一段文字,客戶端打印反饋的信息

客戶端:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

/*
 * 文件複製,需求:將客戶端的文件發到服務端,進行磁盤存儲
 * */
public class CopyOfTCP_cli_04優化版 {
    public static void main(String[] args) throws UnknownHostException, IOException {
        Socket s=new Socket("127.0.0.1",10011);
        //獲取輸出流,將字節轉化爲字符,可以一次寫一行數據
        PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
        //讀取文件,用到了帶緩衝的Reader,可以一次讀取一行
        BufferedReader br=new BufferedReader(new FileReader("E:\\a.txt"));
        String line=null;
        while((line=br.readLine())!=null){
            pw.println(line);
        }
        //文件發送完成,需要發送一個結束標記                要格外注意
        pw.println("over");  //或者使用s.shutdownOutput();
        
        BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream()));
        
        while((line=in.readLine())!=null)
        {
            System.out.println("服務器說:"+line);
        }
        br.close();
        in.close();
        pw.close();
        s.close();
                
    }
}

服務端:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class CopyOfTCP_ser_04優化版 {
    public static void main(String[] args) throws IOException {
        ServerSocket ss=new ServerSocket(10011);
        
        
        Socket s=ss.accept();
        //接受客戶端發送的文件,用到了緩衝,並且將字節流轉化爲了字符流
        BufferedReader br =new BufferedReader(new InputStreamReader(s.getInputStream()));
        //向文件中寫數據,用到了緩衝,可以寫一行
        BufferedWriter bo=new BufferedWriter(new FileWriter("E:\\BB.txt"));
        //向客戶端寫數據,用到了將字節流包裝爲Printwriter 從而可以將字節轉化爲字符串處理
        PrintWriter out=new PrintWriter(s.getOutputStream(),true);
        String line=null;
        while((line=br.readLine())!=null){
            if("over".equals(line))
                break;
            bo.write(line);
            bo.newLine();
            bo.flush();
        }
        out.println("文件收到");
        out.flush();
        s.close();
        
        
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章