天天看點

Java學習路線-39:網絡程式設計TCP、UDP資料傳輸第35 章 : 網絡程式設計

第35 章 : 網絡程式設計

152 網絡程式設計簡介

網絡程式設計: 多台主機之間的資料通信

通信協定:IP、TCP(可靠資料連接配接)、UDP(不可靠資料連接配接)

網絡程式模型:

C/S Client/Server 用戶端/服務端 安全性高 開發成本高

B/S Browser/Server 浏覽器/伺服器 安全性較低 開發成本低

目前以B/S 結構為主

153 Echo程式模型

ServerSocket與Socket

ServerSocket 設定伺服器監聽端口

Socket 設定要連接配接伺服器的ip和端口

實作一個用戶端與伺服器端通信 Echo服務

Server.java

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class Server {
    public static void main(String[] args) throws IOException {
        // 設定伺服器監聽端口
        ServerSocket server = new ServerSocket(8080);
        System.out.println("服務啟動。。。");

        // 接收用戶端連接配接
        Socket client = server.accept();

        // 接收用戶端消息
        Scanner scanner = new Scanner(client.getInputStream());
        scanner.useDelimiter("\n");

        // 發送給用戶端資料
        PrintWriter out = new PrintWriter(client.getOutputStream());

        // 結束标志
        boolean flag = true;

        while (flag) {
            if (scanner.hasNext()) {
                // 讀取用戶端資料
                String message = scanner.next();
                System.out.println("收到: " + message);

                // 結束标志
                if ("bye".equalsIgnoreCase(message)) {
                    flag = false;
                }

                // 發送資料給用戶端
                out.println("[echo] " + message);
                out.flush();
            }
        }

        // 關閉
        out.close();
        scanner.close();
        client.close();
        server.close();
    }
}
      

Client.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    private final static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

    public static void main(String[] args) throws IOException {
        // 連接配接伺服器
        Socket client = new Socket("localhost", 8080);

        // 接收伺服器資訊
        Scanner scanner = new Scanner(client.getInputStream());
        scanner.useDelimiter("\n");

        // 向伺服器發送資訊
        PrintWriter out = new PrintWriter(client.getOutputStream());

        // 結束标志
        boolean flag = true;

        while (flag) {
            // 讀取控制台輸入,發送給伺服器
            String message = getInput("請輸入:");
            System.out.println("發送:" + message);
            out.println(message);
            out.flush();

            // 接收服務端傳回的資料
            if (scanner.hasNext()) {
                System.out.println("傳回:" + scanner.next());
            }

            // 結束标志
            if ("bye".equalsIgnoreCase(message)) {
                flag = false;
            }
        }

        // 關閉操作
        out.close();
        scanner.close();
        client.close();

    }

    // 接收控制台輸入
    public static String getInput(String prompt) throws IOException {
        System.out.println(prompt);
        return reader.readLine();
    }
}
      

154 BIO處理模型

多線程接收多個用戶端連接配接

隻用修改服務端代碼

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class Server {

    public static class ClientThread implements Runnable {
        private Socket client = null;
        private Scanner scanner = null;
        private PrintWriter out = null;
        private boolean flag = true; // 結束标志

        ClientThread(Socket client) throws IOException {
            this.client = client;
            // 接收用戶端消息
            this.scanner = new Scanner(client.getInputStream());
            this.scanner.useDelimiter("\n");

            // 發送給用戶端資料
            this.out = new PrintWriter(client.getOutputStream());
        }

        @Override
        public void run() {
            while (this.flag) {
                if (this.scanner.hasNext()) {
                    // 讀取用戶端資料
                    String message = this.scanner.next();
                    System.out.println("收到: " + Thread.currentThread() + message);

                    // 結束标志
                    if ("bye".equalsIgnoreCase(message)) {
                        this.flag = false;
                    }

                    // 發送資料給用戶端
                    this.out.println("[echo] " + message);
                    this.out.flush();
                }
            }
            this.out.close();
            this.scanner.close();
            try {
                this.client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws IOException {
        // 設定伺服器監聽端口
        ServerSocket server = new ServerSocket(8080);
        System.out.println("服務啟動。。。");

        while (true) {
            // 接收用戶端連接配接
            Socket client = server.accept();
            new Thread(new ClientThread(client)).start();
        }

        // 關閉
        // server.close();
    }
}
      

155 UDP程式

UDP 基于資料報實作

TCP要保證可靠連接配接,需要的伺服器資源就多

不管用戶端是否接收到

Receiver.java

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

public class Receiver {

    public static void main(String[] args) throws IOException {
        DatagramSocket receiver = new DatagramSocket(9000);

        byte[] data = new byte[2014];
        DatagramPacket packet = new DatagramPacket(data, data.length);

        // 等待接收資料
        receiver.receive(packet);
        System.out.println(new String(data, 0, packet.getLength()));

        // 關閉
        receiver.close();
    }

}
      

Sender.java

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

public class Sender {
    public static void main(String[] args) throws Exception {
        DatagramSocket sender = new DatagramSocket(9001);

        // 發送資料
        String message = "Hello world";
        DatagramPacket packet = new DatagramPacket(message.getBytes(), 0, message.length(), InetAddress.getByName("localhost"), 9000);
        sender.send(packet);

        // 關閉
        sender.close();

    }
}