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!