Jelenlegi hely

22.3.2 Olvasás és írás a socket-ről

Nézzünk egy egyszerű példát arra, hogy hogyan lehet kiépíteni egy kapcsolatot a szerver programmal a Socket osztályt használva, azután megnézzük, hogy hogyan tud a kliens adatot küldeni és fogadni a szervertől a socket-en keresztül.

A példaprogram része az EchoClient, ami össze van kötve az echo szerverrel. Az echo szerver elég egyszerűen tud adatot fogadni a klienstől és választ küldeni rá. Az echo szerver egy jól ismert kiszolgáló, amit a kliens a 7-es port-on keresztül tud elérni.

Az EchoClient létrehoz egy socket-et azzal, hogy kapcsolódik az echo szerverhez. Ez beolvas a felhasználótól egy sort, elküldi az echo szervernek a socket-en keresztül. A szerver ezen keresztül válaszol a kliensnek. A kliens program olvassa ezt, és kiírja az adatot, amit visszaküldött neki a szerver:

import java.io.*;
import java.net.*;
public class EchoClient {
    public static void main(String[] args) throws IOException {        Socket echoSocket = null;
        PrintWriter out = null;
        BufferedReader in = null;
        try {
            echoSocket = new Socket("taranis", 7);
            out = new PrintWriter(echoSocket.getOutputStream(),
                                  true);
            in = new BufferedReader(new InputStreamReader(
                                 echoSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println(
                "Az alábbi host nem ismert: taranis.");
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for "
                              + "Kapcsolódás ehhez: taranis.");
            System.exit(1);
        }
    BufferedReader stdIn = new BufferedReader(
                            new InputStreamReader(System.in));
    String userInput;
    while ((userInput = stdIn.readLine()) != null) {
        out.println(userInput);
        System.out.println("echo: " + in.readLine());
    }

    out.close();
    in.close();
    stdIn.close();
    echoSocket.close();
    }
}

Az EchoClient olvasni és írni is tud a socket-ről azáltal, hogy átküld és átvesz adatot az echo szervertől.

Nézzük a program érdekesebb részeit. A main metódus try blokkjában szereplő sorok kiépítik a kapcsolatot a socket-en keresztül a kliens és a szerver között, és megnyitják a PrintWriter-t és a BufferedReader-t a socket-en.

echoSocket = new Socket("taranis", 7);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
                             echoSocket.getInputStream()));

Sorrendben az első rész létrehozza az új Socket objektumot, és nevet ad neki: echoSocket. A Socket konstruktor használata igényli annak a gépnek a nevét és a port-jának a számát, amelyikkel a kapcsolatot létre akarjuk hozni. A példa program a taranis host nevet használja. Ez a helyi hálózatunk virtuális gépének a neve. Mikor futtatjuk a programunkat, akkor saját szerver gépünk host neve kerüljön ide. A 7-es porton figyel az echo szerver.

A második sor összekapcsolja a Socket kimenetét és a PrintWriter-t. A harmadik sor hasonló ehhez, összekapcsolja a Socket bemenetét és a BufferedReader-t. A példa Unicode karaktereket tud írni a socket-en át.

Az EchoClient-nek az adatok socket-en való elküldéséhez egyszerűen a PrintWriter-hez kell írnia. Ahhoz, hogy megkapja a szerver válaszát, olvasnia kell a BufferedReader-ről. A program hátralevő részét ez teszi ki.

A while ciklus a program következő érdekes része. A ciklus beolvas egy sort egy bizonyos idő alatt a szabványos bementről, és azonnal elküldi azt a szervernek a PrintWriter-be való írással, ami a sockethez kapcsolódik:

String userInput;
while ((userInput = stdIn.readLine()) != null) {
    out.println(userInput);
    System.out.println("echo: " + in.readLine());
}

A while ciklus utolsó sorában beolvas egy sor szöveget a BufferedReader-ről, ami a socket-hez kapcsolódik. A readLine metódus addig vár, amíg a szerver válaszol az információra az EchoClient-nek. Mikor a readLine válaszol, az EchoClient kiírja a szöveget a szabványos kimenetre.

A while ciklus addig tart, amíg a felhasználó be nem gépeli az utolsó karaktert. Vagyis az EchoClient olvas a felhasználó bemenetéről, majd elküldi ezt az echo szervernek, kap egy választ a szervertől, és utána kiírja azt, amíg az elér az utolsó karakterig. A while ciklus ekkor bezárul, és a program folytatódik, futtatja a kód következő négy sorát:

out.close();
in.close();
stdIn.close();
echoSocket.close();

A kód e sorai a takarítást végzik. A jó program mindig kitakarít maga után, és ez a program is ilyen. Ezek a részek bezárják az olvasót és az írót, ami a socket-hez kapcsolódik és a szabványos kimenetet és bemenetet is, ami a szerverhez kapcsolódik. A sorrend itt nagyon fontos. Be kell zárnunk minden folyamatot, ami a socket-hez kapcsolódik, mielőtt kikapcsoljuk magát a socket-et.

  • Socket megnyitása.
  • Kimeneti és bementi folyam megnyitása a socket-en.
  • Olvasás és írás a szerver protokollja szerint.
  • A folyamatok bezárása.
  • Socket bezárása.