Skip to main content

Socket (TCP & UDP) communication in Java

Socket communication in Java enables communication between two endpoints over a network. There are two main types of sockets: TCP sockets and UDP sockets. Let's explain both types with examples: TCP Socket Communication: 1. **Server Side**:    - The server creates a `ServerSocket` object to listen for incoming connections on a specific port.    - When a client connects, the server accepts the connection and creates a `Socket` object to communicate with the client.    - The server reads from and writes to the socket's input and output streams to communicate with the client. import java.io.*; import java.net.*; public class TCPServer {     public static void main(String[] args) throws IOException {         ServerSocket serverSocket = new ServerSocket(12345);         System.out.println("Server started. Waiting for client...");         Socket clientSocket = serverSocket.accept();         System.out.println("Client connected.");         BufferedReader in = new Bu

Buffered Streams

Buffered Streams in Java:

Buffered streams are used to improve the performance of input/output operations by reducing the number of system calls. They achieve this by using an internal buffer to read from or write to the underlying input/output stream in larger chunks, rather than one byte or character at a time.


Buffered Input Stream Classes:

- `BufferedInputStream`: Provides buffering for input bytes, allowing the reading of data from an underlying input stream.

- `BufferedReader`: Reads text from a character-input stream, buffering characters to provide efficient reading of characters, arrays, and lines.


Buffered Output Stream Classes:

- `BufferedOutputStream`: Provides buffering for output bytes, allowing the writing of data to an underlying output stream.

- `BufferedWriter`: Writes text to a character-output stream, buffering characters to provide efficient writing of characters, arrays, and lines.


Example: Reading from a File using BufferedReader:


import java.io.BufferedReader;

import java.io.FileReader;

import java.io.IOException;


public class BufferedStreamExample {

    public static void main(String[] args) {

        try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {

            String line;

            while ((line = reader.readLine()) != null) {

                System.out.println(line);

            }

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}



Explanation:

- In this example, we use `BufferedReader` to read text from a file ("example.txt").

- We wrap a `FileReader` with a `BufferedReader` to buffer the input and improve reading performance.

- The `readLine()` method of `BufferedReader` reads a line of text from the input stream. If the end of the stream is reached, it returns `null`.

- We use a `try-with-resources` statement to automatically close the `BufferedReader` when the block ends, ensuring proper resource management.


Benefits of Buffered Streams:

- Reduced number of system calls: Buffered streams reduce the number of system calls by reading or writing data in larger chunks.

- Improved performance: Buffered streams typically provide faster read/write operations compared to their unbuffered counterparts.

- Convenient API: Buffered streams offer convenient methods for reading and writing data, such as `readLine()` in `BufferedReader` for reading lines of text.


------------------------


Here's an example demonstrating the usage of `BufferedWriter` in Java:


import java.io.BufferedWriter;

import java.io.FileWriter;

import java.io.IOException;


public class BufferedWriterExample {

    public static void main(String[] args) {

        String filename = "output.txt";


        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) {

            writer.write("Hello, World!");

            writer.newLine(); // Write a newline character


            // Writing multiple lines

            writer.write("This is an example of BufferedWriter.");

            writer.newLine();

            writer.write("It provides efficient writing of characters, arrays, and lines.");


            System.out.println("Data has been written to " + filename);

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}


Explanation:

- We create a `BufferedWriter` object and wrap it around a `FileWriter`, specifying the file name ("output.txt") to write to.

- Using the `write()` method, we write a string to the file. The `newLine()` method is called to insert a newline character after each line.

- Multiple lines of text are written to the file using separate `write()` calls.

- The `try-with-resources` statement is used to automatically close the `BufferedWriter` when the block ends, ensuring proper resource management.

- If any `IOException` occurs during the writing process, it is caught and the stack trace is printed.


This example demonstrates how `BufferedWriter` can efficiently write text data to a file by buffering the output, which can lead to improved performance compared to writing directly to the file.

----------------


Here's a program that reads input from the user using `BufferedReader` and writes it to a file using `BufferedWriter`:


import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileWriter;

import java.io.IOException;

import java.io.InputStreamReader;


public class BufferedIOExample {

    public static void main(String[] args) {

        try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

             BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {


            // Read input from the user

            System.out.println("Enter text (type 'exit' to quit):");

            String line;

            while (!(line = reader.readLine()).equalsIgnoreCase("exit")) {

                // Write input to a file

                writer.write(line);

                writer.newLine(); // Write a newline character

            }


            System.out.println("Data has been written to output.txt");

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}



Explanation:

- We create a `BufferedReader` object `reader` to read input from the user via `System.in`.

- We create a `BufferedWriter` object `writer` to write data to a file named "output.txt".

- Inside the `while` loop, we continuously read lines of input from the user using `reader.readLine()`.

- If the user types "exit", the loop terminates.

- For each line read from the user, we write it to the file using `writer.write(line)` and add a newline character using `writer.newLine()`.

- The `try-with-resources` statement ensures that both `reader` and `writer` are properly closed after use.

- If any `IOException` occurs during the process, it is caught and the stack trace is printed.



In summary, buffered streams in Java improve I/O performance by reducing system calls and providing efficient buffering of data. They are commonly used in applications where I/O performance is critical, such as reading/writing large files or network communication.

Comments

Popular posts from this blog

Method Overloading in Java

Method Overloading in Java Method Overloading  is a feature in Java that allows a class to have multiple methods with the same name but different parameter lists. The methods can have a different number or types of parameters. The decision on which method to invoke is made by the compiler based on the arguments provided during the method call.  Example: public class Calculator {     // Method to add two integers     public int add(int a, int b) {         return a + b;     }     // Method to add three integers     public int add(int a, int b, int c) {         return a + b + c;     }     // Method to add two doubles     public double add(double a, double b) {         return a + b;     }     // Method to concatenate two strings     public String concatenate(String str1, String str2) {         return str1 + str2;     } } Method Overloading in Action: public class Main {     public static void main(String[] args) {         Calculator calculator = new Calculator();         // Overloaded meth

Java Runtime Environment (JRE)

Definition : Java Runtime Environment (JRE) is a set of software tools and libraries that enables the execution of Java applications. It provides the necessary runtime support for Java programs to run on various devices and platforms. Components of Java Runtime Environment (JRE): Java Virtual Machine (JVM): Definition: The JVM is a crucial component of the JRE responsible for executing Java bytecode. Functionality: It interprets Java bytecode or, in some cases, uses Just-In-Time (JIT) compilation to translate bytecode into native machine code for improved performance. Importance: JVM abstracts the underlying hardware, allowing Java programs to be platform-independent. Class Libraries: Definition: JRE includes a set of precompiled classes and methods that Java applications can utilize. Functionality: These classes cover a wide range of functionalities, from basic data structures to networking. Importance: Class libraries provide a foundation for developers, offering reusable code