java:sockets

This is an old revision of the document!


A PCRE internal error occured. This might be caused by a faulty plugin

====== TCP/IP Sockets ====== Ας υποθέσουμε ότι έχουμε δύο υπολογιστές, έναν εξυπηρετητή (server) και ένα πελάτη (client) οι οποίοι θέλουν να επικοινωνήσουν μεταξύ τους. Ο εξυπηρετητής "ακούει" (listens) σε μία συγκεκριμένη πόρτα (π.χ. 8888) για νέες συνδέσεις. Ο πελάτης θέλει να μιλήσει στον εξυπηρετητή κάνοντας μία σύνδεση στην συγκεκριμένη πόρτα. Ο εξυπηρετητής λαμβάνοντας τη σύνδεση στην πόρτα που "ακούει" ελέγχει αν συντρέχουν λόγοι ασφαλείας να απορρίψει τη σύνδεση από τον συγκεκριμένο πελάτη. Αν δεν συντρέχουν λόγοι ασφαλείας τότε αποδέχεται τη σύνδεση δημιουργώντας ένα νέο socket στο δικό του άκρο με port number διαφορετικό από εκείνο στο οποίο ακούει. Η σύνδεση πραγματοποιείται ο και εξυπηρετητής συνεχίζει να "ακούει" για νέες συνδέσεις. Το παραπάνω δίνονται εποπτικά από το παρακάτω σχήμα. {{ :java:socket-connect.png |}} Το πακέτο java.net της Java παρέχει την κλάση, [[http://docs.oracle.com/javase/7/docs/api/java/net/Socket.html|Socket]], που υλοποιεί μία πλευρά μίας αμφίδρομης σύνδεσης μεταξύ ενός προγράμματος σε Java και ενός άλλου προγράμματος (όχι απαραίτητα σε java) μέσα από το δίκτυο. Η κλάση Socket χρησιμοποιεί την υποδομή των sockets του λειτουργικού συστήματος, κρύβοντας τις λεπτομέρειες του κάθε συστήματος από το πρόγραμμα σας και απαιτώντας ένα ενιαίο API ανεξάρτητα από το λειτουργικό σύστημα που βρίσκεται από κάτω. Επιπλέον, η Java περιλαμβάνει την κλάση [[http://docs.oracle.com/javase/7/docs/api/java/net/ServerSocket.html|ServerSocket]], η οποία υλοποιεί ένα server-side socket το οποίο ακούει σε συγκεκριμένη πόρτα και αποδέχεται συνδέσεις από τον έξω κόσμο. Δείτε τα παρακάτω προγράμματα πελάτη/εξυπηρετητή τα οποία επικοινωνούν μεταξύ τους. Συγκεκριμένα ο πελάτης συνδέεται στον εξυπηρετητή και αποστέλλει περιεχόμενο το οποίο διαβάζει από το standard input. Ο εξυπηρετητής διαβάζει αυτό που του έστειλε ο πελάτης και του το επιστρέφει πίσω. Ο πελάτης λαμβάνει τελικά πίσω αυτό που αρχικά έστειλε στον εξυπηρετητή. <code java EchoServer.java> mport java.net.*; import java.io.*; public class EchoServer { public static void main(String[] args) throws IOException { if (args.length != 1) { System.err.println("Usage: java EchoServer <port number>"); System.exit(1); } int portNumber = Integer.parseInt(args[0]); try ( ServerSocket serverSocket = new ServerSocket(Integer.parseInt(args[0])); Socket clientSocket = serverSocket.accept(); PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream())); ) { String inputLine; while ((inputLine = in.readLine()) != null) { out.println(inputLine); System.out.println("echoing: "+inputLine); } } 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()); } } } </code> <code java EchoClient.java> import java.io.*; import java.net.*; public class EchoClient { public static void main(String[] args) throws IOException { if (args.length != 2) { System.err.println( "Usage: java EchoClient <host name> <port number>"); System.exit(1); } String hostName = args[0]; int portNumber = Integer.parseInt(args[1]); 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) { out.println(userInput); System.out.println("echoed : "+in.readLine()); } } 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); } } } </code> Για να εκτελέσετε τα δύο προγράμματα θα πρέπει να εκκινήσετε πρώτα το //EchoServer// δηλώνοντας το port στο οποίο θα ακούει (π.χ. ''java EchoServer 8888''). Στην συνέχεια εκκινείτε το //EchoClient// ως εξής ''java EchoClient localhost 8888''. Η σύνδεση μέσω sockets δεν υλοποιεί κάποιο πρωτόκολλο επικοινωνίας σε επίπεδο application μεταξύ των δύο άκρων (π.χ. http, ftp). Δύο παραλλαγές των παρακάτω προγραμμάτων είναι η παρακάτω. Στο πρόγραμμα //EchoClient.java// πρώτα δημιουργείται το socket και μετά γίνεται connect σε συγκεκριμένη διεύθυνση (hostname, portnumber). Αντίστοιχα στο πρόγραμμα //EchoServer// πρώτα δημιουργείται το socket και στη συνέχεια γίνεται bind το server socket σε συγκεκριμένη διεύθυνση ("localhost", portnumber). <code java EchoServer.java> import java.net.*; import java.io.*; public class EchoServer { public static void main(String[] args) throws IOException { if (args.length != 1) { System.err.println("Usage: java EchoServer <port number>"); System.exit(1); } int portNumber = Integer.parseInt(args[0]); try ( ServerSocket serverSocket = new ServerSocket(); ) { serverSocket.bind(new InetSocketAddress("localhost", Integer.parseInt(args[0]) ) ); try ( Socket clientSocket = serverSocket.accept(); PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream())); ) { // no catch here System.out.println("Connected to "+clientSocket.getInetAddress().toString()+":"+clientSocket.getPort()); String inputLine; while ((inputLine = in.readLine()) != null) { out.println(inputLine); System.out.println("echoing: "+inputLine); } } 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()); } } } } </code> <code java EchoClient.java> import java.io.*; import java.net.*; public class EchoClient { public static void main(String[] args) throws IOException { if (args.length != 2) { System.err.println( "Usage: java EchoClient <host name> <port number>"); System.exit(1); } String hostName = args[0]; int portNumber = Integer.parseInt(args[1]); InetSocketAddress socketAddress = new InetSocketAddress(hostName, portNumber); try ( Socket echoSocket = new Socket(); BufferedReader stdIn = new BufferedReader( new InputStreamReader(System.in)); ) { echoSocket.connect(socketAddress); System.out.println("Connected to "+echoSocket.getInetAddress().toString()+":"+echoSocket.getPort()); try ( PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true); BufferedReader in = new BufferedReader( new InputStreamReader(echoSocket.getInputStream() )); ) { String userInput; while ((userInput = stdIn.readLine()) != null) { out.println(userInput); System.out.println("echoed: "+in.readLine()); } } // no catch } 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); } finally { } } } </code>

java/sockets.1427197560.txt.gz · Last modified: 2016/02/26 11:15 (external edit)