1. 程式人生 > >Java學習--網路程式設計知識

Java學習--網路程式設計知識

一、網路程式設計概述
計算機網路之間以何種規則進行通訊,就是網路模型研究問題。
網路模型一般是指OSI(Open System Interconnection開放系統互連)七層參考模型,TCP/IP四層參考模型
主機至網路層(物理層 , 資料鏈路層) , 網際層 , 傳輸層 , 應用層(應用層 , 表示層 , 會話層)
二、協議
1.TCP/IP協議
Tcp是指傳輸控制協議
Ip是指網路地址協議
TCP/IP協議族按層次分別分為以下四層:應用層、傳輸層、網路層和資料鏈路層。
應用層
應用層決定了向用戶提供應用服務時通訊的活動
FTP(檔案傳輸協議)、 http( 超文字傳輸協議)、 ssh(遠端登入)、telnet (遠端登入)DNS(域名系統)都屬於該層
傳輸層
傳輸層對上層應用層提供處於網路連線中兩臺計算機之間的資料傳輸。
TCP(保障資料的可靠有序), UDP( 不保證資料可靠性)都屬於傳輸層
網路層
網路層用於處理網路上流動的資料包。該層規定了通過怎樣的路徑到達對方的計算機,並把資料傳送給對方。
ip協議屬於網路層
鏈路層
鏈路層用來處理連線網路的硬體部分
2.HTTP協議
HTTP協議是位於應用層的協議。
2.1)請求
請求方式 資源地址 協議版本
請求首部欄位(包括主機埠號)
例如:
GET /index.html HTTP/1.1
Host: localhost
2.2)響應
協議版本 狀態碼 狀態碼的原因短語
響應首部欄位
三、使用telnet客戶端程式
a.進入控制面板,在“程式”裡找到“開啟或關閉Windous功能”裡找到telnet客戶端並打勾
b.開啟cmd命令視窗
c.與伺服器端建立連線
輸入:telnet 對方ip 埠號(80)
d.以http協議傳送請求
傳送完成後需要兩個回車
e.接受返回結果

四、客戶端程式設計
1.Socket程式設計
a建立Scoket
Socket socket = new Socket(“ip地址”, 埠號);
b發資料
socket.getOutputStream();
c收資料
socket.getInputStream();
編寫一個簡單的客戶端程式,從客戶端以http形式傳送請求,在接受資料

public class testSocket {
    public static void main(String[] args) throws IOException {
    	//1.建立Scoket
        Socket socket = new Socket("localhost", 4396);
        OutputStream out = socket.getOutputStream();
        InputStream in = socket.getInputStream();
        //2.發資料
        out.write("GET /index.html HTTP/1.1\n".getBytes());
        out.write("Host: localhost\n".getBytes());
        out.write("\n\n".getBytes());
        3.收資料
        byte[] bt = new byte[1024 * 8];
        while(true){
            int l =in.read(bt);
            System.out.println(new String(bt, 0, l));
        }
        socket.close();
    }
}

2.URL程式設計
a建立連線併發送請求
HttpURLConnection connection = (HttpURLConnection)new URL(“http:主機地址:埠號/資源地址”).openConnection();
b接受資料
InputStream in = connection.getInputStream();
示例:從伺服器端拿到一張圖片並儲存到本地。

public class TestURL {
    public static void main(String[] args) throws IOException {
        // 127.0.0.1 <==> localhost
        HttpURLConnection connection = (HttpURLConnection)new URL("http://192.168.3.123:80/img/chrome.png").openConnection();
   
        InputStream in = connection.getInputStream();
        FileOutputStream image = new FileOutputStream("e:\\2.png");
        while(true) {
            byte[] buf = new byte[1024*8];
            int len = in.read(buf);
            if(len == -1) {
                break;
            }
            image.write(buf, 0, len);
        }
        image.close();
        connection.disconnect();
    }
}

五、伺服器端程式設計
a.一次只能響應一個客戶端的程式:

public class testSeverSocket {
    public static void main(String[] args) throws IOException {
    	//1.建立serverSocket
        ServerSocket serverSocket = new ServerSocket(4396);
		//2.呼叫accept 等待客戶端連線
        Socket accept = serverSocket.accept();
        InputStream in = accept.getInputStream();
        OutputStream out = accept.getOutputStream();
        byte[] bt = new byte[1024*8];
        while(true){
        //3.接收客戶的輸入
            int  len=in.read(bt);
            if(len==-1)
                break;
            //4. 拿到輸出流向客戶寫入
            out.write(bt,0,len);
        }
    }
}

b.通過多執行緒,為每一個客戶端程式都建立一個執行緒去處理。

public class ThreadServerSocket {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(4396);
        while(true){
            Socket accept = serverSocket.accept();
            new Thread(()->{
                try {
                    control(accept);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

    private static void control(Socket accept) throws IOException {
        InputStream in = accept.getInputStream();
        OutputStream out = accept.getOutputStream();
        byte[] bt = new byte[1024*8];
        while(true){
           int  len=in.read(bt);
            if(len==-1)
                break;
            out.write(bt,0,len);
        }
    }
}

c.執行緒池
ExecutorService service = new ThreadPoolExecutor(,corePoolSize maxPoolSize, keepAliveTime , timeUnit, TimeUnit.SECONDS,BlockingQueue);
(1)corePoolSize 核心執行緒數。
(2)maxPoolSize 最大執行緒數 核心執行緒數+救急執行緒數<=最大執行緒數。
(3)keepAliveTime 保持時間 如果一個執行緒閒暇的時間超過了保持時間,那就把它回收,但不會少於核心執行緒數。
(4)timeUnit 時間單位。
(5)BlockingQueue 阻塞佇列 當任務數超過核心執行緒數後,就把任務放入阻塞佇列排隊執行 (有界,無界)。

public static void main(String[] args) throws IOException {
        // 1. 建立serverSocket
        ServerSocket serverSocket = new ServerSocket(5000);
        System.out.println("服務已啟動,等待連線");
        ExecutorService service = new ThreadPoolExecutor(10, 10, 0, TimeUnit.SECONDS,new LinkedBlockingQueue<>());

        while(true) {
            Socket socket = serverSocket.accept();
            System.out.println("客戶端已連線....");
            service.submit(() -> {
                try {
                    handle(socket);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }
    }
    private static void handle(Socket socket) throws IOException {
        InputStream in = socket.getInputStream();
        OutputStream out = socket.getOutputStream();
        while (true) {
            byte[] buf = new byte[1024];
            int len = in.read(buf);
            if (len == -1) {
                break;
            }
            String echo = new String(buf, 0, len, "utf-8");
            System.out.println(echo);
            out.write(("伺服器回答:" + echo).getBytes("utf-8"));
        }
    }
}