Program o architekturze klient – serwer napisany w Javie, służący jako prosty komunikator tekstowy. Przykład zaczerpnięty z podręcznika „Java dla programistów C++”.
Dla systemów Linux i Windows nie kompilować osobno – ten sam plik .class zadziała w obu systemach. Jeśli posiadamy najnowszą Javę i obawiamy się, że na innym komputerze będzie starszy interpreter kompilujemy kod poleceniem:
1 | "C:\Program Files\Java\jdk1.7.0_02\bin\javac" -source 1.2 -target 1.2 JavaTalker.java |
Parametry source i target wskazują w jakiej wersji Java (najstarszej) wszystkie biblioteki programu były obecne (tu: wersja 1.7 udaje wersje 1.2). Z dystrybucjami Linuxa często nie jest dostarczana najnowsza wersja interpretera B-code.
Tak skompilowany kod uruchamiamy na jednym komputerze w trybie serwera (np. Linux, program otworzy domyślnie port 500). Dodajmy, że program uruchamia się w trybie tekstowym, nie wymaga X-servera.
1 | java JavaTalker -server |
a na drugim jako klient łączymy się z serwerem (może być to komputer np. w systemie Windows):
1 | java JavaTalker -port 500 192.168.1.9 |
adres IP zmieniamy na adres naszego serwera Java oczekującego na połączenie.
Jest to też przykład na to, jak umieścić trzy klasy w jednym pliku Java (zazwyczaj każda klasa ma kod zapisany w osobnym pliku).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | import java.io.*; import java.net.*; public class JavaTalker { boolean server; int port = 500; //domyślny port Socket sock; String host = null; public void parseArgs(String args[]) { //funkcja interpretuje parametry wejściowe wpisywane z konsoli przy uruchamianiu: int i=0; while (i < args.length) { if (args[i].equals("-port")) { port = Integer.valueOf(args[i+1]).intValue(); //pobranie numeru portu z następnego argumentu -port 300 i+=2; // przejście o 2 argumenty dalej } else if (args[i].equals("-server")) { server = true; //tryb serwera będzie uruchamiany i++; } else if (i != args.length-1) { System.out.println("Uzycie:"); //wpisano błędnie parametry - wypisujemy więc help: System.out.println(" (server) JavaTalker [-port port] [-server]"); System.out.println(" (klient) JavaTalker [-port port] [hostname]"); System.exit(0); } else { host = args[i]; i++; } } } public static void main(String args[]) { //funkcja statyczna - uruchamiana analogicznie do main() w C++ new JavaTalker(args); //ponieważ funkcja jest statyczna - tworzy "swój" obiekt } public JavaTalker(String args[]) { //Konstruktor klasy parseArgs(args); //interpretuj parametry tekstowe wejścia if (server) //trzeba uruchomić klienta czy serwer? server(); else client(); } public void busyWait(DataInputStream inStream) { try { while (inStream.available() <= 0) { Thread.currentThread().sleep(100); } } catch (InterruptedException e) { System.out.println(e.getMessage()); } catch (IOException e) { System.out.println(e.getMessage()); } } public void server() { //odpalenie serwera try { InetAddress serverAddr = InetAddress.getByName(null); System.out.println("Czekam na polaczenie na maszynie " + serverAddr.getHostName() + " na porcie " + port + "." ); ServerSocket serverSock = new ServerSocket(port,50); sock = serverSock.accept(); System.out.println( "Przyjalem polaczenie z "+ sock.getInetAddress().getHostName()+"."); new JavaTalkerWriter(this).start(); new JavaTalkerReader(this).start(); } catch (IOException e) { System.out.println(e.getMessage()+" blad polaczenia z klientem."); } } public void client() { //uruchomienie klienta try { InetAddress serverAddr = InetAddress.getByName(host); sock = new Socket(serverAddr.getHostName(), port, true); System.out.println("Polaczenie z serverem " + serverAddr.getHostName() + " na porcie " + sock.getPort() + "."); new JavaTalkerWriter(this).start(); new JavaTalkerReader(this).start(); } catch (IOException e) { System.out.println(e.getMessage() + ":Brak polaczenia z serverem."); } } } class JavaTalkerReader extends Thread { //osobna klasa odbierająca komunikat JavaTalker talker; public JavaTalkerReader(JavaTalker talker) { this.talker = talker; } public synchronized void run() { try { DataInputStream userIn = new DataInputStream(System.in); DataOutputStream remoteOut = new DataOutputStream(talker.sock.getOutputStream()); while (true) { talker.busyWait(userIn); remoteOut.writeChars(userIn.readLine() + '\n'); } } catch (IOException e) { System.out.println(e.getMessage()); System.out.println(": Polaczenie zerwane." ); } } } class JavaTalkerWriter extends Thread { //trzecia klasa wysyła komunikat JavaTalker talker; public JavaTalkerWriter( JavaTalker talker ) { this.talker = talker; } public synchronized void run() { try { DataInputStream remoteIn = new DataInputStream(talker.sock.getInputStream()); while (true) { talker.busyWait(remoteIn); System.out.println(remoteIn.readLine()); } } catch (IOException e) { System.out.println(e.getMessage()); System.out.println(": Polaczenie zerwane."); } } } |