Java คือ ตอนที่ 12 : ระบบเครือข่าย (Networking)

  1. พื้นฐานของระบบเครือข่ายใน Java
    IP Address
    พอร์ต (Ports)
    โปรโตคอล (Protocols)
  2. คลาสเครือข่าย (Networking Classes) Java และอินเทอร์เฟซ (Interfaces)
  3. การทำแอพเครือข่าย

เมื่อเราเจาะลึกลงไปในความแตกต่างของการทำแอพ Java เราได้พบกับคุณลักษณะที่มีศักยภาพของเครือข่าย Java โดยพื้นฐานแล้ว Java Networking เป็นแนวคิดที่เกี่ยวข้องกับการทำแอพที่สามารถสื่อสารผ่านเครือข่ายได้ การสื่อสารนี้อาจอยู่ระหว่างกระบวนการต่างๆ ในเครื่องเดียวกันหรือกระบวนการในทวีปต่างๆ คุณลักษณะสำคัญที่เปิดใช้งานนี้คือแพ็คเกจ java.net ซึ่งให้การสนับสนุนทั้งโปรโตคอลที่เน้นการเชื่อมต่อ (TCP) และโปรโตคอลที่ไม่มีการเชื่อมต่อ (UDP) บทความนี้มีจุดประสงค์เพื่อไม่เพียงแค่อธิบายทฤษฎีของ Java Networking เท่านั้น แต่ยังแนะนำคุณในการทำแอพบนเครือข่ายอย่างง่ายอีกด้วย

1. พื้นฐานของระบบเครือข่ายใน Java

ก่อนที่เราจะพูดถึงความซับซ้อนของระบบเครือข่ายใน Java สิ่งสำคัญคือต้องเข้าใจแนวคิดพื้นฐานของระบบเครือข่าย

IP Address

ที่อยู่ IP (Internet Protocol) เป็นตัวระบุเฉพาะสำหรับอุปกรณ์ภายในเครือข่าย ที่อยู่นี้ใช้เพื่อส่งข้อมูลระหว่างอุปกรณ์อย่างถูกต้อง ใน Java คลาส InetAddress แสดงถึงที่อยู่ IP

พอร์ต (Ports)

พอร์ตเป็นจุดสิ้นสุดของการสื่อสารโดยพื้นฐานแล้ว เป็นตัวระบุเฉพาะที่ช่วยให้ระบบระบุว่ากระบวนการเฉพาะใดที่จะกำหนดเส้นทางคำขอของเครือข่าย การรวมกันของที่อยู่ IP และพอร์ตเรียกว่าซ็อกเก็ต และนี่คือหลักสำคัญของการสื่อสารผ่านเครือข่าย

โปรโตคอล (Protocols)

โปรโตคอล เช่น TCP (Transmission Control Protocol) หรือ UDP (User Datagram Protocol) กำหนดวิธีการส่งและรับข้อมูล TCP เป็นโปรโตคอลที่เน้นการเชื่อมต่อ เพื่อให้มั่นใจว่าข้อมูลถูกส่งและรับอย่างน่าเชื่อถือ ในทางตรงกันข้าม UDP นั้นไม่มีการเชื่อมต่อและไม่รับประกันว่าจะส่งข้อมูลได้สำเร็จ แต่จะเร็วกว่า

2. คลาสเครือข่าย (Networking Classes) Java และอินเทอร์เฟซ (Interfaces)

ในแพ็คเกจ java.net Java มีคลาสและอินเตอร์เฟสมากมายที่ทำให้การเขียนโปรแกรมเครือข่ายง่ายขึ้น เช่น:

  • InetAddress:คลาสนี้แสดงถึงที่อยู่ IP
  • Socket และ ServerSocket:คลาสเหล่านี้เป็นตัวแทนของไคลเอนต์และเซิร์ฟเวอร์ในโปรโตคอลที่เน้นการเชื่อมต่อ (TCP)
  • DatagramPacket, DatagramSocket และ MulticastSocket:คลาสเหล่านี้ใช้สำหรับการส่งแพ็กเก็ตแบบไม่มีการเชื่อมต่อ (UDP)

3. การทำแอพเครือข่าย

ในทางปฏิบัติ เราจะทำแอพไคลเอ็นต์-เซิร์ฟเวอร์อย่างง่าย โดยไคลเอนต์ (Client) ส่งข้อความไปยังเซิร์ฟเวอร์ (Server) และเซิร์ฟเวอร์สะท้อนกลับ (echoes back)

เซิฟเวอร์ (Server)

เซิร์ฟเวอร์ของเราจำเป็นต้องรับฟังคำขอของไคลเอ็นต์ (client) ที่เข้ามาและประมวลผล นี่คือการใช้งานง่ายๆ:

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

public class EchoServer {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(5000)) {
            System.out.println("Server is running...");

            while (true) {
                Socket socket = serverSocket.accept();

                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                String line;
                while ((line = in.readLine()) != null) {
                    System.out.println("Received from client: " + line);
                    out.println("Server echo: " + line);
                }
            }
        } catch (IOException e) {
            System.out.println("Error in server: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

โค้ดเซิร์ฟเวอร์นี้ทำสิ่งต่อไปนี้:

  • เปิด ServerSocket พอร์ต 5,000
  • เข้าสู่วงวนไม่สิ้นสุดที่รอการเชื่อมต่อไคลเอ็นต์ด้วย serverSocket.accept()
  • อ่านข้อความของไคลเอ็นต์ (client) ด้วยไฟล์ BufferedReader.
  • ส่งเสียงสะท้อนกลับไปยังไคลเอ็นต์โดยใช้ไฟล์ PrintWriter.

ไคลเอ็นต์ (Client)

งานของไคลเอ็นต์ (client) คือการเชื่อมต่อกับเซิร์ฟเวอร์ ส่งข้อความ และรับการตอบกลับ

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

public class EchoClient {
    public static void main(String[] args) {
        String hostname = "localhost";
        int port = 5000;

        try (Socket socket = new Socket(hostname, port)) {
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));

            String userInput;
            while ((userInput = stdIn.readLine()) != null) {
                out.println(userInput);
                System.out.println("Echo from server: " + in.readLine());
            }
        } catch (UnknownHostException e) {
            System.err.println("Unknown host: " + hostname);
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to " + hostname);
            System.exit(1);
        }
    }
}

โค้ดของไคลเอ็นต์ (client) ทำสิ่งต่อไปนี้:

  • เชื่อมต่อกับเซิร์ฟเวอร์ที่ localhost พอร์ต 5000 โดยใช้ไฟล์ Socket
  • อ่านอินพุตของผู้ใช้จากคอนโซล System.in และส่งไปยังเซิร์ฟเวอร์
  • อ่านการตอบสนองของเซิร์ฟเวอร์และพิมพ์ไปยังคอนโซล

เมื่อเซิร์ฟเวอร์ทำงานในหน้าต่างคอนโซลเดียว คุณสามารถเริ่มไคลเอนต์ในอีกหน้าต่างหนึ่งได้ เมื่อคุณพิมพ์ข้อความลงในคอนโซลไคลเอ็นต์ เซิร์ฟเวอร์ควรสะท้อนกลับ


การสำรวจเครือข่าย Java นี้ให้พื้นฐานการทำแอพบนเครือข่ายใน Java แม้ว่าเราจะเพียงแค่ขูดพื้นผิวของเครือข่าย แต่โค้ดด้านบนควรให้แนวคิดที่ชัดเจนแก่คุณเกี่ยวกับวิธีการตั้งค่าการสื่อสารระหว่างไคลเอ็นต์และเซิร์ฟเวอร์

การทำแอพเครือข่ายในโลกแห่งความเป็นจริงอาจซับซ้อนกว่ามาก เกี่ยวข้องกับไคลเอ็นต์หลายเครื่อง เธรดสำหรับจัดการการเชื่อมต่อหลายรายการพร้อมกัน และการจัดการข้อผิดพลาดที่มีประสิทธิภาพ อย่างไรก็ตาม ด้วยพื้นฐานเหล่านี้ คุณสามารถสำรวจหัวข้อเครือข่าย Java ที่ซับซ้อนยิ่งขึ้นได้ เช่น non-blocking I/O (NIO), Secure Sockets Layer (SSL) หรือความสามารถที่มีให้โดยเฟรมเวิร์กอย่าง Netty หรือ Spring ในการทำแอพ


Java คืออะไร

Java คือ ตอนที่ 11 : การทำงานพร้อมกัน (Concurrency)
Java คือ ตอนที่ 13 : การทดสอบ (Testing) และการดีบัก (Debugging)