Java का Socket Programming
In this page:
ServerSocket server = new ServerSocket(port);
Socket socket = server.accept();
Socket client = new Socket("host", port);
ServerSocket Basics
ServerSocket वह class है जिसका उपयोग आप server applications लिखने के लिए करते हैं: यह किसी specific port से bind होकर सुनता है, फिर किसी client के connect होने तक accept() पर block करता है। यह समझना ज़रूरी है कि accept() block करता है, क्योंकि एक naive server एक समय में सिर्फ एक client से बात कर पाएगा जब तक आप connections को दूसरे threads को न सौंपें।
उदाहरण: ServerSocket Basics
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(0); // OS picks a free port
new Thread(() -> {
try (Socket client = server.accept()) { // blocks until a client connects
System.out.println("Client connected");
} catch (Exception e) {}
}).start();
new Socket("localhost", server.getLocalPort());
Thread.sleep(100);
server.close();
}
}
Login to try C/C++/Java/PHP code in the editor
Socket Client Basics
Socket class किसी server से client-side connection को represent करता है। आप इसके constructor को server का hostname और port देकर connect करते हैं, जिस समय Java TCP handshake करता है और आपको data असल में exchange करने के लिए input/output streams देता है।
उदाहरण: Socket Client Basics
import java.net.*;
public class Main {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(0);
new Thread(() -> { try { server.accept(); } catch (Exception e) {} }).start();
Socket client = new Socket("localhost", server.getLocalPort()); // TCP handshake happens here
System.out.println("Connected: " + client.isConnected());
client.close();
server.close();
}
}
Login to try C/C++/Java/PHP code in the editor
Bidirectional Socket Communication
आप किसी background thread में ServerSocket शुरू करके bidirectional communication establish कर सकते हैं ताकि यह आपके बाकी program को block किए बिना connections accept कर सके, फिर कहीं और से इससे एक client Socket connect कर सकें। Connect होने के बाद, दोनों पक्ष उसी underlying TCP connection पर स्वतंत्र रूप से पढ़ते और लिखते हैं।
उदाहरण: Bidirectional Socket Communication
// Import java.net.* so it can be used by its short name
import java.net.*;
// Import java.io.* so it can be used by its short name
import java.io.*;
// Define the class Main
public class Main {
// Program entry point: the JVM starts running here
public static void main(String[] args) throws Exception {
// Create a new ServerSocket object and store it in server
ServerSocket server = new ServerSocket(0);
// Create a new Thread object and store it in serverThread
Thread serverThread = new Thread(() -> {
// Try code that might throw an exception
try (Socket s = server.accept()) {
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
// Print a line to the console
System.out.println("Server received: " + in.readLine());
new PrintWriter(s.getOutputStream(), true).println("reply");
} catch (Exception e) {}
});
serverThread.start();
Socket client = new Socket("localhost", server.getLocalPort());
new PrintWriter(client.getOutputStream(), true).println("hello");
BufferedReader clientIn = new BufferedReader(new InputStreamReader(client.getInputStream()));
System.out.println("Client received: " + clientIn.readLine());
client.close();
server.close();
}
}
Login to try C/C++/Java/PHP code in the editor
Multi-Threaded Server
एक साथ कई clients handle करने के लिए, एक अच्छी तरह designed server हर accepted connection को accept loop पर inline process करने के बजाय अपने खुद के thread (या thread-pool task) को सौंपता है। इसके बिना, एक अकेला धीमा या hanging client हर दूसरे client को serve होने का इंतज़ार करवा सकता है।
उदाहरण: Multi-Threaded Server
import java.net.*;
public class Main {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(0);
Runnable acceptLoop = () -> {
try {
for (int i = 0; i < 2; i++) {
Socket client = server.accept();
new Thread(() -> System.out.println("Handling a client on its own thread")).start(); // delegated, not inline
client.close();
}
} catch (Exception e) {}
};
new Thread(acceptLoop).start();
new Socket("localhost", server.getLocalPort()).close();
new Socket("localhost", server.getLocalPort()).close();
Thread.sleep(100);
server.close();
}
}
Login to try C/C++/Java/PHP code in the editor
Closing Sockets Safely
काम हो जाने के बाद हमेशा socket streams और connection resources close करें, क्योंकि leaked sockets load के तहत किसी server के उपलब्ध file descriptors को खत्म कर सकते हैं। try-with-resources statement इस cleanup को अपने आप handle करता है, operation के बीच में किसी exception के फेंके जाने पर भी sockets और streams को close करते हुए।
उदाहरण: Closing Sockets Safely
import java.net.*;
public class Main {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(0);
new Thread(() -> { try { server.accept().close(); } catch (Exception e) {} }).start();
try (Socket client = new Socket("localhost", server.getLocalPort())) { // try-with-resources closes automatically
System.out.println("Connected and will auto-close");
}
server.close();
}
}
Login to try C/C++/Java/PHP code in the editor
- किसी socket पर
readLine()का उपयोग करना और दूसरी तरफ से newline न भेजना, जिससे यह line के अंत का इंतज़ार करते हुए हमेशा के लिए block हो जाता है। - clients को एक-एक करके एक single thread पर handle करना, जिससे दूसरे client को पहले के disconnect होने तक इंतज़ार करना पड़ता है।
- socket और उसकी streams को close न करना, या किसी ऐसे port पर server शुरू करना जो पहले से उपयोग में है, जो
BindExceptionफेंकता है।
Chapter Quiz — Complete all 4 topics to unlock
0/4 topics done
Complete these topics first: