Java 網絡編程case

Java 網絡編程

網絡編程三要素

  • IP 地址:設備在網絡中的地址,是唯一的標識。
  • 端口號:應用程序在設備中的唯一標識。取值範圍 0 ~ 65535,一般 0 ~1023 之間的端口用於固定網絡服務或系統應用,一般自己使用 1024 以上的端口。一個端口只能被一個應用程序使用。
  • 協議:數據在網絡中傳輸的規則,常見協議有 UDP 和 TCP。

InetAddress 類

該類表示 IP 地址。

  • getByName:根據主機名獲取 InetAddress 對象。
  • getHostName:獲取主機名。
  • getHostAddress:以字符串形式獲取 IP 地址。

例:

public static void main(String[] args) throws UnknownHostException {
    InetAddress inetAddress = InetAddress.getByName("localhost");
    System.out.println("主機名爲:" + inetAddress.getHostName());
    System.out.println("IP地址爲:" + inetAddress.getHostAddress());
}

UDP 通信

UDP 的三種通信方式:

單播

發送端代碼:

public class UDPClient {

    public static void main(String[] args) throws Exception {
        // 創建發送端 socket 對象
        DatagramSocket socket = new DatagramSocket();
        // 打包要發送的數據
        byte[] bytes = "HELLO UDP".getBytes();
        InetAddress address = InetAddress.getByName("localhost");
        int port = 8080;
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, port);
        // 發送數據
        socket.send(packet);
        // 釋放資源
        socket.close();
    }

}

接收端代碼:

public class UDPServer {

    public static void main(String[] args) throws Exception{
        // 創建接收端 socket 對象,表示從 8080 端口接收數據
        DatagramSocket socket = new DatagramSocket(8080);
        // 準備接收數據
        byte[] bytes = new byte[1024];
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
        // 接收數據
        socket.receive(packet);
        // 獲取數據
        int length = packet.getLength();
        System.out.println(new String(bytes, 0, length));
        // 釋放資源
        socket.close();
    }

}

如果接收端沒有接收到數據,會在 socket.receive(packet); 處阻塞。


組播

組播地址 224.0.0.0 ~ 239.255.255.255,其中 224.0.0.0 ~224.0.0.255 不可用。

發送端代碼:

public class UDPClient {

    public static void main(String[] args) throws Exception {
        // 創建發送端 socket 對象
        DatagramSocket socket = new DatagramSocket();
        // 打包要發送的數據
        byte[] bytes = "HELLO UDP".getBytes();
        // 224.0.1.0 表示組播地址
        InetAddress address = InetAddress.getByName("224.0.1.0");
        int port = 8080;
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, port);
        // 發送數據
        socket.send(packet);
        // 釋放資源
        socket.close();
    }

}

接收端代碼:

public class UDPServer {

    public static void main(String[] args) throws Exception{
        // 創建接收端 socket 對象(注意使用 MulticastSocket),從 8080 端口接收數據,
        MulticastSocket socket = new MulticastSocket(8080);
        // 準備接收數據
        byte[] bytes = new byte[1024];
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
        // 把當前計算機綁定到組播地址
        socket.joinGroup(InetAddress.getByName("224.0.1.0"));
        // 接收數據
        socket.receive(packet);
        // 獲取數據
        int length = packet.getLength();
        System.out.println(new String(bytes, 0, length));
        // 釋放資源
        socket.close();
    }

}

廣播

發送端代碼:

public class UDPClient {

    public static void main(String[] args) throws Exception {
        // 創建發送端 socket 對象
        DatagramSocket socket = new DatagramSocket();
        // 打包要發送的數據
        byte[] bytes = "HELLO UDP".getBytes();
        InetAddress address = InetAddress.getByName("255.255.255.255");
        int port = 8080;
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, port);
        // 發送數據
        socket.send(packet);
        // 釋放資源
        socket.close();
    }

}

接收端代碼:

public class UDPServer {

    public static void main(String[] args) throws Exception{
        // 創建接收端 socket 對象,表示從 8080 端口接收數據
        DatagramSocket socket = new DatagramSocket(8080);
        // 準備接收數據
        byte[] bytes = new byte[1024];
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
        // 接收數據
        socket.receive(packet);
        // 獲取數據
        int length = packet.getLength();
        System.out.println(new String(bytes, 0, length));
        // 釋放資源
        socket.close();
    }

}

TCP 通信

TCP 在通信兩端各建立一個 Socket 對象,發送端是 Socket,接收端是 ServerSocket,通信之前要保證連接已經建立。

發送端代碼:

public class TCPClient {

    public static void main(String[] args) throws Exception{
        // 創建發送端 socket
        Socket socket = new Socket("localhost", 8080);
        // 獲取字節輸出流
        OutputStream os = socket.getOutputStream();
        // 寫數據
        os.write("hello tcp".getBytes());
        // 釋放資源
        os.close();
        socket.close();
    }

}

接收端代碼:

public class TCPServer {

    public static void main(String[] args) throws Exception{
        // 創建接收端 socket
        ServerSocket serverSocket = new ServerSocket(8080);
        // 獲取客戶端連接 socket,獲取不到將阻塞
        Socket socket = serverSocket.accept();
        // 獲取字節輸入流
        InputStream is = socket.getInputStream();
        // 讀數據,如果發送端沒有釋放資源會阻塞
        int b;
        while ((b = is.read()) != -1){
            System.out.print((char)b);
        }
        // 釋放資源
        is.close();
        socket.close();
        serverSocket.close();
    }

}

TCP 練習1:雙方互相發送數據

客戶端:發送數據,接收服務器反饋。

public class TCPClient {

    public static void main(String[] args) throws Exception{
        // 創建發送端 socket
        Socket socket = new Socket("localhost", 8080);
        // 獲取字節輸出流併發送數據
        OutputStream os = socket.getOutputStream();
        os.write("hello tcp".getBytes());
        // 寫一個結束標記,關閉輸出流
        socket.shutdownOutput();
        // 獲取字符輸入流並讀取反饋
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line;
        while ((line = br.readLine()) != null){
            System.out.print(line);
        }
        // 釋放資源
        br.close();
        os.close();
        socket.close();
    }

}

服務器:接收數據,給出反饋。

public class TCPServer {

    public static void main(String[] args) throws Exception{
        // 創建接收端 socket
        ServerSocket serverSocket = new ServerSocket(8080);
        // 獲取客戶端連接 socket,獲取不到將阻塞
        Socket socket = serverSocket.accept();
        // 獲取字節輸入流並讀取數據
        InputStream is = socket.getInputStream();
        int b;
        while ((b = is.read()) != -1){
            System.out.print((char)b);
        }
        // 獲取字符輸出流並反饋
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bw.write("已收到");
        // 釋放資源
        bw.close();
        is.close();
        socket.close();
        serverSocket.close();
    }

}

TCP 練習2:文件上傳

客戶端:將本地文件上傳到服務器,接收服務器反饋。

public class FileUpload {

    public static void main(String[] args) throws Exception{
        // 創建客戶端 socket
        Socket socket = new Socket("localhost", 8080);
        // 要上傳的文件
        File file = new File("C:\\a.jpg");
        // 本地字節輸入流,讀取文件
        InputStream is = new FileInputStream(file);
        // 網絡字節輸出流,上傳文件
        OutputStream os = socket.getOutputStream();
        byte[] bytes = new byte[1024];
        int read;
        while ((read = is.read(bytes)) != -1){
            os.write(bytes, 0, read);
        }
        socket.shutdownOutput();
        // 接收服務端提示
        is = socket.getInputStream();
        while ((read = is.read()) != -1){
            System.out.print((char)read);
        }
        // 釋放資源
        is.close();
        os.close();
        socket.close();
    }
}

服務器:接收客戶端上傳的文件,接收成功後給出反饋。

public class FileReceive {

    public static void main(String[] args) throws Exception{
        // 創建服務端 socket
        ServerSocket serverSocket = new ServerSocket(8080);
        // 接收客戶端 socket
        Socket socket = serverSocket.accept();
        // 網絡字節輸入流,讀取文件
        InputStream is = socket.getInputStream();
        // 本地字節輸出流,保存到對應文件夾
        OutputStream os = new FileOutputStream(new File("C:\\b.jpg"));
        byte[] bytes = new byte[1024];
        int read;
        while ((read = is.read(bytes)) != -1){
            os.write(bytes, 0, read);
        }
        // 提示客戶端上傳成功
        os = socket.getOutputStream();
        os.write("file upload successfully".getBytes());
        // 釋放資源
        os.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章