- พื้นฐานของระบบเครือข่ายใน Java
IP Address
พอร์ต (Ports)
โปรโตคอล (Protocols) - คลาสเครือข่าย (Networking Classes) Java และอินเทอร์เฟซ (Interfaces)
- การทำแอพเครือข่าย
เมื่อเราเจาะลึกลงไปในความแตกต่างของการทำแอพ 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 ในการทำแอพ