Java - ระบบเครือข่าย
คำว่าการเขียนโปรแกรมเครือข่ายหมายถึงการเขียนโปรแกรมที่ดำเนินการกับอุปกรณ์หลายเครื่อง (คอมพิวเตอร์) ซึ่งอุปกรณ์ทั้งหมดเชื่อมต่อกันโดยใช้เครือข่าย
แพ็คเกจ java.net ของ J2SE API มีคอลเล็กชันของคลาสและอินเทอร์เฟซที่ให้รายละเอียดการสื่อสารระดับต่ำช่วยให้คุณสามารถเขียนโปรแกรมที่เน้นการแก้ปัญหาในมือ
แพ็คเกจ java.net รองรับโปรโตคอลเครือข่ายทั่วไปสองโปรโตคอล -
TCP- TCP ย่อมาจาก Transmission Control Protocol ซึ่งช่วยให้การสื่อสารที่เชื่อถือได้ระหว่างสองแอปพลิเคชัน โดยทั่วไปจะใช้ TCP ผ่านอินเทอร์เน็ตโปรโตคอลซึ่งเรียกว่า TCP / IP
UDP - UDP ย่อมาจาก User Datagram Protocol ซึ่งเป็นโปรโตคอลที่ไม่ต้องเชื่อมต่อซึ่งช่วยให้สามารถส่งแพ็กเก็ตข้อมูลระหว่างแอปพลิเคชันได้
บทนี้ให้ความเข้าใจที่ดีในสองเรื่องต่อไปนี้ -
Socket Programming - นี่เป็นแนวคิดที่ใช้กันอย่างแพร่หลายในระบบเครือข่ายและได้รับการอธิบายอย่างละเอียด
URL Processing- สิ่งนี้จะครอบคลุมแยกต่างหาก คลิกที่นี่เพื่อเรียนรู้เกี่ยวกับการประมวลผล URLในภาษา Java
การเขียนโปรแกรมซ็อกเก็ต
ซ็อกเก็ตจัดเตรียมกลไกการสื่อสารระหว่างคอมพิวเตอร์สองเครื่องโดยใช้ TCP โปรแกรมไคลเอ็นต์สร้างซ็อกเก็ตที่ส่วนท้ายของการสื่อสารและพยายามเชื่อมต่อซ็อกเก็ตนั้นกับเซิร์ฟเวอร์
เมื่อทำการเชื่อมต่อเซิร์ฟเวอร์จะสร้างอ็อบเจ็กต์ซ็อกเก็ตที่จุดสิ้นสุดของการสื่อสาร ขณะนี้ไคลเอนต์และเซิร์ฟเวอร์สามารถสื่อสารโดยการเขียนและอ่านจากซ็อกเก็ต
คลาส java.net.Socket แสดงถึงซ็อกเก็ตและคลาส java.net.ServerSocket จัดเตรียมกลไกสำหรับโปรแกรมเซิร์ฟเวอร์เพื่อรับฟังไคลเอ็นต์และสร้างการเชื่อมต่อกับพวกเขา
ขั้นตอนต่อไปนี้เกิดขึ้นเมื่อสร้างการเชื่อมต่อ TCP ระหว่างคอมพิวเตอร์สองเครื่องโดยใช้ซ็อกเก็ต -
เซิร์ฟเวอร์สร้างอินสแตนซ์อ็อบเจ็กต์ ServerSocket แสดงว่าการสื่อสารหมายเลขพอร์ตใดที่จะเกิดขึ้น
เซิร์ฟเวอร์เรียกใช้วิธีการยอมรับ () ของคลาส ServerSocket วิธีนี้จะรอจนกว่าไคลเอ็นต์จะเชื่อมต่อกับเซิร์ฟเวอร์บนพอร์ตที่กำหนด
หลังจากเซิร์ฟเวอร์กำลังรอไคลเอ็นต์จะสร้างอินสแตนซ์อ็อบเจ็กต์ Socket โดยระบุชื่อเซิร์ฟเวอร์และหมายเลขพอร์ตที่จะเชื่อมต่อ
ตัวสร้างของคลาส Socket พยายามเชื่อมต่อไคลเอ็นต์กับเซิร์ฟเวอร์ที่ระบุและหมายเลขพอร์ต หากมีการสร้างการสื่อสารไคลเอนต์จะมีอ็อบเจ็กต์ Socket ที่สามารถสื่อสารกับเซิร์ฟเวอร์ได้
ในฝั่งเซิร์ฟเวอร์วิธีการ accept () จะส่งคืนการอ้างอิงไปยังซ็อกเก็ตใหม่บนเซิร์ฟเวอร์ที่เชื่อมต่อกับซ็อกเก็ตของไคลเอ็นต์
หลังจากสร้างการเชื่อมต่อแล้วการสื่อสารสามารถเกิดขึ้นได้โดยใช้สตรีม I / O แต่ละซ็อกเก็ตมีทั้ง OutputStream และ InputStream OutputStream ของไคลเอ็นต์เชื่อมต่อกับ InputStream ของเซิร์ฟเวอร์และ InputStream ของไคลเอ็นต์เชื่อมต่อกับ OutputStream ของเซิร์ฟเวอร์
TCP เป็นโปรโตคอลการสื่อสารสองทางดังนั้นข้อมูลจึงสามารถส่งผ่านทั้งสองสตรีมได้ในเวลาเดียวกัน ต่อไปนี้เป็นคลาสที่มีประโยชน์ซึ่งมีชุดวิธีการที่สมบูรณ์ในการติดตั้งซ็อกเก็ต
วิธีการคลาส ServerSocket
java.net.ServerSocket คลาสถูกใช้โดยเซิร์ฟเวอร์แอ็พพลิเคชันเพื่อรับพอร์ตและรับฟังคำขอของไคลเอ็นต์
คลาส ServerSocket มีตัวสร้างสี่ตัว -
ซีเนียร์ | วิธีการและคำอธิบาย |
---|---|
1 | public ServerSocket(int port) throws IOException พยายามสร้างซ็อกเก็ตเซิร์ฟเวอร์ที่เชื่อมโยงกับพอร์ตที่ระบุ ข้อยกเว้นเกิดขึ้นหากพอร์ตถูกผูกไว้แล้วโดยแอ็พพลิเคชันอื่น |
2 | public ServerSocket(int port, int backlog) throws IOException คล้ายกับตัวสร้างก่อนหน้าพารามิเตอร์ backlog ระบุจำนวนไคลเอ็นต์ขาเข้าที่จะจัดเก็บในคิวรอ |
3 | public ServerSocket(int port, int backlog, InetAddress address) throws IOException คล้ายกับตัวสร้างก่อนหน้านี้พารามิเตอร์ InetAddress ระบุที่อยู่ IP ในเครื่องที่จะผูก InetAddress ใช้สำหรับเซิร์ฟเวอร์ที่อาจมีที่อยู่ IP หลายรายการทำให้เซิร์ฟเวอร์สามารถระบุที่อยู่ IP ที่จะยอมรับคำขอของไคลเอ็นต์ได้ |
4 | public ServerSocket() throws IOException สร้างซ็อกเก็ตเซิร์ฟเวอร์ที่ไม่ถูกผูกไว้ เมื่อใช้ตัวสร้างนี้ให้ใช้เมธอด bind () เมื่อคุณพร้อมที่จะผูกซ็อกเก็ตเซิร์ฟเวอร์ |
หากตัวสร้าง ServerSocket ไม่ทิ้งข้อยกเว้นหมายความว่าแอ็พพลิเคชันของคุณเชื่อมโยงกับพอร์ตที่ระบุสำเร็จและพร้อมสำหรับการร้องขอของไคลเอ็นต์
ต่อไปนี้เป็นวิธีการทั่วไปบางส่วนของคลาส ServerSocket -
ซีเนียร์ | วิธีการและคำอธิบาย |
---|---|
1 | public int getLocalPort() ส่งคืนพอร์ตที่ซ็อกเก็ตเซิร์ฟเวอร์กำลังรับฟัง วิธีนี้มีประโยชน์ถ้าคุณส่ง 0 เป็นหมายเลขพอร์ตในตัวสร้างและปล่อยให้เซิร์ฟเวอร์ค้นหาพอร์ตให้คุณ |
2 | public Socket accept() throws IOException รอลูกค้าที่เข้ามา วิธีนี้บล็อกจนกว่าไคลเอ็นต์จะเชื่อมต่อกับเซิร์ฟเวอร์บนพอร์ตที่ระบุหรือซ็อกเก็ตหมดเวลาโดยสมมติว่ามีการตั้งค่าการหมดเวลาโดยใช้เมธอด setSoTimeout () มิฉะนั้นวิธีนี้จะบล็อกไปเรื่อย ๆ |
3 | public void setSoTimeout(int timeout) ตั้งค่าการหมดเวลาสำหรับระยะเวลาที่ซ็อกเก็ตเซิร์ฟเวอร์รอไคลเอ็นต์ระหว่างการยอมรับ () |
4 | public void bind(SocketAddress host, int backlog) ผูกซ็อกเก็ตกับเซิร์ฟเวอร์ที่ระบุและพอร์ตในอ็อบเจ็กต์ SocketAddress ใช้วิธีนี้หากคุณสร้างอินสแตนซ์ ServerSocket โดยใช้ตัวสร้างไม่มีอาร์กิวเมนต์ |
เมื่อ ServerSocket เรียกใช้ accept () เมธอดจะไม่ส่งคืนจนกว่าไคลเอ็นต์จะเชื่อมต่อ หลังจากไคลเอนต์ทำการเชื่อมต่อ ServerSocket จะสร้างซ็อกเก็ตใหม่บนพอร์ตที่ไม่ระบุและส่งกลับการอ้างอิงไปยังซ็อกเก็ตใหม่นี้ ขณะนี้มีการเชื่อมต่อ TCP ระหว่างไคลเอนต์และเซิร์ฟเวอร์และการสื่อสารสามารถเริ่มต้นได้
วิธีการคลาสของซ็อกเก็ต
java.net.Socketคลาสแสดงถึงซ็อกเก็ตที่ทั้งไคลเอนต์และเซิร์ฟเวอร์ใช้สื่อสารกัน ไคลเอนต์รับอ็อบเจ็กต์ Socket โดยการสร้างอินสแตนซ์หนึ่งในขณะที่เซิร์ฟเวอร์รับอ็อบเจ็กต์ Socket จากค่าส่งคืนของวิธีการยอมรับ ()
คลาส Socket มีคอนสตรัคเตอร์ห้าตัวที่ไคลเอนต์ใช้เพื่อเชื่อมต่อกับเซิร์ฟเวอร์ -
ซีเนียร์ | วิธีการและคำอธิบาย |
---|---|
1 | public Socket(String host, int port) throws UnknownHostException, IOException. วิธีนี้พยายามเชื่อมต่อกับเซิร์ฟเวอร์ที่ระบุที่พอร์ตที่ระบุ หากตัวสร้างนี้ไม่เกิดข้อยกเว้นแสดงว่าการเชื่อมต่อสำเร็จและไคลเอนต์เชื่อมต่อกับเซิร์ฟเวอร์ |
2 | public Socket(InetAddress host, int port) throws IOException เมธอดนี้เหมือนกับตัวสร้างก่อนหน้ายกเว้นว่าโฮสต์ถูกแสดงโดยอ็อบเจ็กต์ InetAddress |
3 | public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException. เชื่อมต่อกับโฮสต์และพอร์ตที่ระบุสร้างซ็อกเก็ตบนโลคัลโฮสต์ตามแอดเดรสและพอร์ตที่ระบุ |
4 | public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException. เมธอดนี้เหมือนกับตัวสร้างก่อนหน้านี้ยกเว้นว่าโฮสต์ถูกแสดงโดยอ็อบเจ็กต์ InetAddress แทน String |
5 | public Socket() สร้างซ็อกเก็ตที่ไม่ได้เชื่อมต่อ ใช้วิธีการเชื่อมต่อ () เพื่อเชื่อมต่อซ็อกเก็ตนี้กับเซิร์ฟเวอร์ |
เมื่อตัวสร้างซ็อกเก็ตส่งคืนมันไม่เพียงแค่สร้างอินสแตนซ์อ็อบเจ็กต์ Socket แต่จริงๆแล้วพยายามเชื่อมต่อกับเซิร์ฟเวอร์และพอร์ตที่ระบุ
วิธีการบางอย่างที่น่าสนใจในคลาส Socket แสดงไว้ที่นี่ สังเกตว่าทั้งไคลเอนต์และเซิร์ฟเวอร์มีอ็อบเจ็กต์ Socket ดังนั้นเมธอดเหล่านี้จึงสามารถเรียกใช้ได้ทั้งไคลเอนต์และเซิร์ฟเวอร์
ซีเนียร์ | วิธีการและคำอธิบาย |
---|---|
1 | public void connect(SocketAddress host, int timeout) throws IOException วิธีนี้เชื่อมต่อซ็อกเก็ตกับโฮสต์ที่ระบุ วิธีนี้จำเป็นเฉพาะเมื่อคุณสร้างอินสแตนซ์ Socket โดยใช้ตัวสร้างไม่มีอาร์กิวเมนต์ |
2 | public InetAddress getInetAddress() วิธีนี้จะส่งคืนที่อยู่ของคอมพิวเตอร์เครื่องอื่นที่ซ็อกเก็ตนี้เชื่อมต่ออยู่ |
3 | public int getPort() ส่งคืนพอร์ตที่ซ็อกเก็ตผูกไว้บนเครื่องระยะไกล |
4 | public int getLocalPort() ส่งคืนพอร์ตที่ซ็อกเก็ตเชื่อมโยงกับเครื่องโลคัล |
5 | public SocketAddress getRemoteSocketAddress() ส่งกลับที่อยู่ของรีโมตซ็อกเก็ต |
6 | public InputStream getInputStream() throws IOException ส่งคืนอินพุตสตรีมของซ็อกเก็ต อินพุตสตรีมเชื่อมต่อกับสตรีมเอาต์พุตของซ็อกเก็ตระยะไกล |
7 | public OutputStream getOutputStream() throws IOException ส่งคืนกระแสเอาต์พุตของซ็อกเก็ต สตรีมเอาต์พุตเชื่อมต่อกับอินพุตสตรีมของซ็อกเก็ตระยะไกล |
8 | public void close() throws IOException ปิดซ็อกเก็ตซึ่งทำให้อ็อบเจ็กต์ Socket นี้ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ใด ๆ ได้อีกต่อไป |
วิธีการเรียน InetAddress
คลาสนี้แสดงที่อยู่ Internet Protocol (IP) ต่อไปนี้เป็นวิธีการที่มีประโยชน์ซึ่งคุณจำเป็นต้องใช้ในการเขียนโปรแกรมซ็อกเก็ต -
ซีเนียร์ | วิธีการและคำอธิบาย |
---|---|
1 | static InetAddress getByAddress(byte[] addr) ส่งคืนอ็อบเจ็กต์ InetAddress ที่กำหนดที่อยู่ IP ดิบ |
2 | static InetAddress getByAddress(String host, byte[] addr) สร้าง InetAddress ตามชื่อโฮสต์และที่อยู่ IP ที่ระบุ |
3 | static InetAddress getByName(String host) กำหนดที่อยู่ IP ของโฮสต์โดยระบุชื่อโฮสต์ |
4 | String getHostAddress() ส่งคืนสตริงที่อยู่ IP ในการนำเสนอแบบข้อความ |
5 | String getHostName() รับชื่อโฮสต์สำหรับที่อยู่ IP นี้ |
6 | static InetAddress InetAddress getLocalHost() ส่งคืนโลคัลโฮสต์ |
7 | String toString() แปลงที่อยู่ IP นี้เป็นสตริง |
ตัวอย่าง Socket Client
GreetingClient ต่อไปนี้เป็นโปรแกรมไคลเอ็นต์ที่เชื่อมต่อกับเซิร์ฟเวอร์โดยใช้ซ็อกเก็ตและส่งคำทักทายจากนั้นรอการตอบกลับ
ตัวอย่าง
// File Name GreetingClient.java
import java.net.*;
import java.io.*;
public class GreetingClient {
public static void main(String [] args) {
String serverName = args[0];
int port = Integer.parseInt(args[1]);
try {
System.out.println("Connecting to " + serverName + " on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Just connected to " + client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF("Hello from " + client.getLocalSocketAddress());
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
System.out.println("Server says " + in.readUTF());
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ตัวอย่างเซิร์ฟเวอร์ซ็อกเก็ต
โปรแกรม GreetingServer ต่อไปนี้เป็นตัวอย่างของแอ็พพลิเคชันเซิร์ฟเวอร์ที่ใช้คลาส Socket เพื่อรับฟังไคลเอ็นต์บนหมายเลขพอร์ตที่ระบุโดยอาร์กิวเมนต์บรรทัดคำสั่ง -
ตัวอย่าง
// File Name GreetingServer.java
import java.net.*;
import java.io.*;
public class GreetingServer extends Thread {
private ServerSocket serverSocket;
public GreetingServer(int port) throws IOException {
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(10000);
}
public void run() {
while(true) {
try {
System.out.println("Waiting for client on port " +
serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to " + server.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(server.getInputStream());
System.out.println(in.readUTF());
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress()
+ "\nGoodbye!");
server.close();
} catch (SocketTimeoutException s) {
System.out.println("Socket timed out!");
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
public static void main(String [] args) {
int port = Integer.parseInt(args[0]);
try {
Thread t = new GreetingServer(port);
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
คอมไพล์ไคลเอนต์และเซิร์ฟเวอร์จากนั้นเริ่มเซิร์ฟเวอร์ดังต่อไปนี้ -
$ java GreetingServer 6066
Waiting for client on port 6066...
ตรวจสอบโปรแกรมไคลเอนต์ดังนี้ -
เอาต์พุต
$ java GreetingClient localhost 6066
Connecting to localhost on port 6066
Just connected to localhost/127.0.0.1:6066
Server says Thank you for connecting to /127.0.0.1:6066
Goodbye!