×

Lập Trình Socket Server và Socket Client trong Java

Để thực hiện truyền thông qua socket trong Java, bạn cần hiểu về hai thành phần cơ bản: ServerSocketSocket. ServerSocket chờ đợi các yêu cầu từ phía client qua mạng, trong khi Socket là điểm kết nối ở phía client để gửi và nhận dữ liệu từ server. Dưới đây là một hướng dẫn cơ bản về cách thiết lập một kết nối socket giữa server và client trong Java.

Tạo Server Socket

  1. Khởi tạo ServerSocket: Đầu tiên, tạo một đối tượng ServerSocket với một cổng xác định để nghe các yêu cầu kết nối từ client.
    ServerSocket serverSocket = new ServerSocket(portNumber);
    
  2. Chấp nhận kết nối từ Client: Sử dụng phương thức accept() của ServerSocket để chấp nhận kết nối từ client. Phương thức này sẽ chặn cho đến khi một kết nối được thiết lập và sau đó trả về một đối tượng Socket để giao tiếp với client.
    Socket clientSocket = serverSocket.accept();
    

Tạo Client Socket

  1. Kết nối tới Server: Trên phía client, tạo một đối tượng Socket mới và kết nối tới server bằng địa chỉ IP và cổng đã xác định.
    Socket socket = new Socket(serverAddress, portNumber);
    

Giao Tiếp giữa Server và Client

  • Gửi dữ liệu: Cả server và client đều có thể gửi dữ liệu qua socket bằng cách sử dụng các luồng đầu ra (OutputStream) và viết vào đó.
    // Gửi từ server tới client
    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
    out.println("Hello, Client!");
    
    // Gửi từ client tới server
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    out.println("Hello, Server!");
    
  • Nhận dữ liệu: Tương tự, cả hai bên cũng có thể đọc dữ liệu được gửi qua socket bằng cách sử dụng các luồng đầu vào (InputStream).
    // Server đọc dữ liệu từ client
    BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    String fromClient = in.readLine();
    
    // Client đọc dữ liệu từ server
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    String fromServer = in.readLine();
    

Đóng Kết Nối

Sau khi giao tiếp kết thúc, đừng quên đóng các socket và luồng dữ liệu để giải phóng tài nguyên.

out.close();
in.close();
clientSocket.close(); // Trên server
socket.close(); // Trên client

Lưu ý rằng việc gửi và nhận dữ liệu qua socket có thể xảy ra lỗi do mất mát kết nối, do đó hãy luôn xử lý ngoại lệ một cách cẩn thận trong code thực tế của bạn.

Mã nguồn đầy đủ

  • Phía Server

    import java.io.*;
    import java.net.*;
    
    public class EchoServer {
        public static void main(String[] args) {
            int portNumber = 12345; // Chọn một cổng phù hợp
            try (ServerSocket serverSocket = new ServerSocket(portNumber);
                 Socket clientSocket = serverSocket.accept();
                 PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
                 BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            ) {
                System.out.println("Client connected on port " + portNumber);
                String inputLine;
                while ((inputLine = in.readLine()) != null) { // Đọc dữ liệu gửi từ client
                    System.out.println("Received message: " + inputLine + " from " + clientSocket.toString());
                    out.println(inputLine); // Gửi lại dữ liệu cho client
                }
            } catch (IOException e) {
                System.out.println("Exception caught when trying to listen on port "
                    + portNumber + " or listening for a connection");
                System.out.println(e.getMessage());
            }
        }
    }
    
  • Phía Client
    import java.io.*;
    import java.net.*;
    
    public class EchoClient {
        public static void main(String[] args) {
            String hostName = "127.0.0.1";  // Địa chỉ IP của máy chủ
            int portNumber = 12345; // Cổng phải trùng với cổng mà server đang lắng nghe
    
            try (Socket echoSocket = new Socket(hostName, portNumber);
                 PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
                 BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
                 BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))
            ) {
                String userInput;
                while ((userInput = stdIn.readLine()) != null) { // Đọc dữ liệu từ console
                    out.println(userInput); // Gửi dữ liệu tới server
                    System.out.println("echo: " + in.readLine()); // Đọc phản hồi từ server
                }
            } catch (UnknownHostException e) {
                System.err.println("Don't know about host " + hostName);
                System.exit(1);
            } catch (IOException e) {
                System.err.println("Couldn't get I/O for the connection to " +
                    hostName);
                System.exit(1);
            } 
        }
    }
    
  • Chạy Server: Mở terminal hoặc command prompt, dịch và chạy file EchoServer.java. Server sẽ bắt đầu lắng nghe trên cổng được chỉ định.

  • Chạy Client: Mở một terminal hoặc command prompt khác, dịch và chạy file EchoClient.java. Nhập văn bản vào console của client; văn bản này sẽ được gửi tới server, và server sẽ gửi lại cùng một văn bản như một phản hồi.

Comments