Basal Netværks Kommunikation

Jeg vil fortælle lidt om en af mulighederne til netværks kommunikation, denne artikel er to delt, server og klient, det er forklaret hvordan man, rent teknisk, kan kommunikere over et netværk eller internettet.

PrintWriter og BufferedReader Server

Dette er primært til tekst, hvor "PrintWriter" bruges til at sende tekst, hvor "BufferedReader" bruges til at modtage tekst.

Man kan programmere en kommunikation mellem klient og server, rimelig nemt på denne måde, jeg giver et eksempel på hvordan man opretter server delen først.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class BasicNetworkServer {

	/**
	 * @param args the command line arguments
	 */
	public static void main(String[] args) {
		try {
			ServerSocket socket = new ServerSocket(12345);
			System.out.println("The server is listening on port 12345.");
			try (Socket client = socket.accept()) {
				System.out.println("Connection accepted.");
				PrintWriter out;
				out = new PrintWriter(client.getOutputStream(), true);
				BufferedReader in;
				in = new BufferedReader(new InputStreamReader(client.getInputStream()));
				out.println("Connection accepted.");
				out.println("Try typing \"Gettext\".");
				String msg = in.readLine();
				if (msg.equalsIgnoreCase("Gettext")) {
					out.println("OK.");
				} else {
					out.println("Fail.");
				}
				out.println("No more messages, terminating connection.");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException ex) {
					System.out.println("Interrupt detected.");
				}
				System.out.println("No more messages, terminating program.");
				in.close();
				out.close();
				client.close();
			}
			System.exit(0);
		} catch (IOException ex) {
			System.out.println("An error happened.");
		}
	}
}

Inden at jeg forklarer "PrintWriter" og "BufferedReader", så forklarer jeg lige lidt om "ServerSocket".

For at udbyde noget som helst på netværket, så er man nødsaget til at oprette en "lytter" på en port som man kender, samt ikke er optaget. Dette gøres ved hjælp af "ServerSocket(12345)" objektet, dette er navngivet "socket" i ovenstående sammenhæng, en socket er en lytter, den lytter efter indkomne forbindelser, dette kan vi godt bruge, da vi ellers skulle oprette forbindelse hver gang vi forespørger noget, på denne måde holder vi forbindelsen åben, og kan sende og modtage data som vi lyster. Det skal siges at vi er nødsaget til at acceptere forbindelsen, før at vi sender data til den. Dette gøres ved "socket.accept()", så bliver der skabt en forbindelse der går begge veje, det er nu op til dig hvordan du vil fortsætte.

ServerSocket socket = new ServerSocket(12345);
Socket client = socket.accept();

Det der er væsenligt i denne sammenhæng er at "PrintWriter(client.getOutputStream(), true);" opretter et objekt ("out") som gør det muligt at sende tekst til den anden ende (modtageren), dette gøres igennem metoden "println", for at få det til at fungere, så bruger man "out.println("Noget tekst")". Ordet "true" betyder om der skal sendes data automatisk, ellers ville der kun sendes data når bufferen er fuld, denne kan også være "false", hvor ved bufferen er aktiveret, og man skal bruge "out.flush();" for at tømme bufferen og derved sende data.

out = new PrintWriter(client.getOutputStream(), true);
out.println("Noget tekst");

Nu hvor vi kan sende data, skal vi da også lige kunne modtage data, dettes gør vi brug af "BufferedReader", i ovenstående eksempel bruger vi "BufferedReader(new InputStreamReader(client.getInputStream()));", dette objekt er navngivet "in" og kan bruges ved at tage en linje af gangen, for at behandle disse linjer, vil man gøre dette "String msg = in.readLine();", "msg" vil indeholde ren tekst i dette tilfælde.

in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String msg = in.readLine();

Det der er fælles for "in", "out" og "client" objekterne er at man bruge metoden ".close()" for at lukke forbindelsen igen, som også er vist i eksemplet.

in.close();
out.close();
client.close();

For at lukke selve programmet fra at køre, så skal man blot bruge "System.exit(0)", men i dette tilfælde, er det ikke nødvendigt, da der ikke er mere at eksekvere efterfølgende.

System.exit(0);

PrintWriter og BufferedReader Klient

Vi går videre til klienten, dette er tænkt til at sende en linje tekst til serveren, hvor serveren returnerer enten "OK." eller "Fail.". Dette vil ske når vi sender teksten "Gettext", serveren er lidt ligeglad med om det er store eller små bogstaver, videre til eksemplet.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class BasicNetworkClient {

	/**
	 * @param args the command line arguments
	 */
	public static void main(String[] args) {
		System.out.println("Connecting to localhost on port 12345.");
		try {
			Socket toServer;
			toServer = new Socket("localhost", 12345);
			PrintWriter out;
			out = new PrintWriter(toServer.getOutputStream(), true);
			BufferedReader in;
			in = new BufferedReader(new InputStreamReader(toServer.getInputStream()));
			String msg0 = in.readLine();
			System.out.println(msg0);
			String msg1 = in.readLine();
			System.out.println(msg1);
			out.println("Gettext");
			String msg2 = in.readLine();
			System.out.println(msg2);
			String msg3 = in.readLine();
			System.out.println(msg3);
			in.close();
			out.close();
			toServer.close();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException ex) {
				System.out.println("Interrupt detected.");
			}
			System.exit(0);
		} catch (IOException ex) {
			System.out.println("Unknown host.");
		}
	}
}

Denne klient er lidt lige som server delen, der er dog nogle forskelle.

I stedet for at bruge "ServerSocket", bruges der i stedet "Socket" til at forbinde til serveren, denne metode tager to argumenter, først et host navn (halmark.dk) eller en ip adresse (127.0.0.1 eller ::1) samt et port nummer (1 - 65535).

Socket toServer;
toServer = new Socket("localhost", 12345);

Der er også en metode til at stoppe programmet (enkelt trådet programmer)/tråden (flere trådede programmer) midlertidigt, "Thread.sleep(1000)" denne er mere så vi kan nå at registrere det der kommer på skærmen.

Thread.sleep(1000);

Download Kilde- og byte-kode

Kildekoden er det der er vist i eksemplerne, disse skal først kompileres (oversættes) til bytekode før disse kan køres, alle kildekoder leveres som zip filer, Windows kan selv finde ud af at pakke disse ud, linux har fileroller eller lignende programmer.

Jar er en kompileret udgave af kildekoden, denne er også komprimeret, man kan bruge winrar, eller lignende program, til at pakke denne ud, disse bliver også leveret som zip filer, det er ikke nødvendigt at pakke en jar fil ud, dette kan Java gøre helt af sig selv.

Kildekode til server eksemplet findes her.

Jar med server eksemplet findes her.

Kildekode til klient eksemplet findes her.

Jar med klient eksemplet findes her.