Skip to content

Latest commit

 

History

History
129 lines (91 loc) · 5.68 KB

File metadata and controls

129 lines (91 loc) · 5.68 KB

Theoretical Questions 📝

Three Ways to Send a Login Message

  class LoginRequest implements Serializable {
    String username;
    String password;

    LoginRequest(String username, String password) {
        this.username = username;
        this.password = password;
    }
}
public class Client {
    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("localhost", 5050);

        LoginRequest loginRequest = new LoginRequest("user1", "pass123");
        // === Method 1: Plain String ===
        PrintWriter stringOut = new PrintWriter(socket.getOutputStream(), true);
        stringOut.println("LOGIN|" + loginRequest.username + "|" + loginRequest.password);

        // === Method 2: Serialized Object ===
        ObjectOutputStream objectOut = new ObjectOutputStream(socket.getOutputStream());
        objectOut.writeObject(loginRequest);

        // === Method 3: JSON ===
        Gson gson = new Gson();
        String json = gson.toJson(loginRequest);
        PrintWriter jsonOut = new PrintWriter(socket.getOutputStream(), true);
        jsonOut.println(json);

        socket.close();
    }
}

Note: The server file is not provided as part of this project. You are encouraged to write your own server implementation for testing and running the application.

Questions:

Method 1: Plain String Format

  1. What are the pros and cons of using a plain string like "LOGIN|user|pass"?
  2. How would you parse it, and what happens if the delimiter appears in the data?
  3. Is this approach suitable for more complex or nested data?

Method 2: Serialized Java Object

  1. What’s the advantage of sending a full Java object?
  2. Could this work with a non-Java client like Python?

Method 3: JSON

  1. Why is JSON often preferred for communication between different systems?
  2. Would this format work with servers or clients written in other languages?

Answers:

Method 1: Plain String Format

1:

Pros:

  • Simplicity: Easy to implement and understand, requiring minimal code.
  • Lightweight: No additional libraries or complex serialization is needed.
  • Human-readable: The format can be easily inspected or logged if needed.

Cons:

  • Security Risk: Sending plain text passwords is insecure and vulnerable to interception.
  • Error-prone Parsing: Requires manual parsing on the server side, which can lead to errors if the delimiter is mishandled.
  • Limited Flexibility: Not suitable for complex or nested data structures.
  • No Type Safety: The server must assume the format, increasing the risk of misinterpretation.

2:

On the server side, we can use String.split("|") to split the string into parts. For example:

String data = "LOGIN|user1|pass1234";
String[] parts = data.split("\\|");
String command = parts[0]; // "LOGIN"
String username = parts[1]; // "user1"
String password = parts[2]; // "pass1234"

If the delimiter (|) appears in the username or password (e.g., LOGIN|user|name|pass1234), the split method will produce incorrect parts:

  • Result: ["LOGIN", "user", "name", "pass1234"], leading to misinterpretation (e.g., "name" as password).

3:

No, it is not suitable:

  • Reason: The plain string approach with a simple delimiter (|) is designed for flat, simple data (e.g., key-value pairs or small records). It cannot handle nested structures (e.g., objects within objects) or complex data types (e.g., arrays, lists, or custom objects).
  • Limitation: Parsing nested data would require a custom, error-prone string format (e.g., using brackets or additional delimiters), which is difficult to maintain and extend.
  • Better Alternatives: For complex or nested data, serialized objects (Method 2) or JSON (Method 3) are more appropriate, as they support structured data and are easier to parse with standard libraries.

Method 2: Serialized Java Object

1:

  • Type Safety: Sending a full Java object (e.g., LoginRequest) ensures that the server receives a strongly-typed object, reducing the risk of misinterpretation or parsing errors.
  • Ease of Use: The server can directly cast the received object to the expected type (e.g., LoginRequest) without manual parsing, making the code cleaner and less error-prone.
  • Complex Data Support: Serialized objects can handle complex or nested data structures (e.g., objects with lists, maps, or other objects) easily, as Java's serialization mechanism preserves the object's structure and state.
  • Built-in Mechanism: Java's ObjectOutputStream and ObjectInputStream handle serialization and deserialization automatically, requiring minimal effort to transmit and reconstruct the object.

2:

No, it would not work directly:

  • Reason: Java's serialization format (used by ObjectOutputStream) is specific to Java and relies on Java's class structure and serialization mechanism. A non-Java client like Python cannot natively deserialize Java objects because Python does not understand Java's binary serialization format.

Method 3: JSON

1:

Advantages of JSON:

  • Language-Agnostic: JSON is supported by virtually all programming languages (e.g., Java, Python, JavaScript, C#), making it ideal for cross-platform communication.
  • Human-Readable: Its text-based format is easy to read and debug, unlike binary formats like Java serialization.
  • Lightweight: JSON has a compact structure with minimal overhead compared to XML, improving performance for data transfer.

2:

Yes, it would work:

JSON is a language-agnostic format, meaning servers or clients written in other languages (e.g., Python, JavaScript, C++) can parse and generate JSON data using their respective libraries.