Gr.4. Socket programmering. Gr.4. Innlevering LAB 4. Gruppe 4. oppgaver 01.10.2014

Like dokumenter
Socket og ServerSocket

KTN1 - Design av forbindelsesorientert protokoll

2 Om statiske variable/konstanter og statiske metoder.

INF1010 våren 2019 Onsdag 30. januar. Mer om unntak i Java (med litt repetisjon av I/O først)

JSP - 2. Fra sist. Hvordan fungerer web? Tjenerside script HTML. Installasjon av Web-tjener Et enkelt JSP-script. Ønsker dynamiske nettsider:

Hittil har programmene kommunisert med omverden via tastatur og skjerm Ønskelig at data kan leve fra en kjøring til neste

TOD063 Datastrukturer og algoritmer

Løsningsforslag ukeoppg. 6: 28. sep - 4. okt (INF Høst 2011)

Argumenter fra kommandolinjen

Kapittel 9. Distribusjon. Fjernbruker. Tjenermaskin LAN WAN. Nærbruker. Figur 9-1: En enkel klient/tjener distribusjon

Å lese tall fra en fil, klassen Scanner

UNIVERSITETET I OSLO

LITT OM OPPLEGGET. INF1000 EKSTRATILBUD Stoff fra uke September 2012 Siri Moe Jensen EKSEMPLER

Kapittel 8: Programutvikling

programeksempel Et større En større problemstilling Plan for forelesingen Problemstillingen (en tekstfil) inneholdt ordet "TGA"

Programmering i C++ Løsningsforslag Eksamen høsten 2005

UNIVERSITETET I OSLO

INF 1000 høsten 2011 Uke september

Løsningsforslag Test 2

INF1000 undervisningen INF 1000 høsten 2011 Uke september

Hva er verdien til variabelen j etter at følgende kode er utført? int i, j; i = 5; j = 10; while ( i < j ) { i = i + 2; j = j - 1; }

Litt om pakker og mest om data inn og ut

OPPGAVE 1 OBLIGATORISKE OPPGAVER (OBLIG 1) (1) Uten å selv implementere og kjøre koden under, hva skriver koden ut til konsollen?

UNIVERSITETET I OSLO

Dagens forelesning. Java 13. Rollefordeling (variant 1) Rollefordeling (variant 2) Design av større programmer : fordeling av roller.

Lenkelister. Lister og køer. Kopi av utvalgte sider fra forelesningen.

INF1010 våren 2017 Onsdag 25. januar. Litt om unntak i Java

INF1000 (Uke 5) Mer om løkker, arrayer og metoder

UNIVERSITETET I OSLO

Eksamen i emnet INF100 Grunnkurs i programmering (Programmering I) og i emnet INF100-F Objektorientert programmering i Java I

UNIVERSITETET I OSLO

Jentetreff INF1000 Debugging i Java

TDT4100 Objektorientert programmering

Løsningsforslag ukeoppg. 2: 31. aug - 6. sep (INF Høst 2011)

Oblig 4 (av 4) INF1000, høsten 2012 Værdata, leveres innen 9. nov. kl

Fra Python til Java, del 2

Seminaroppgaver IN1010, uke 2

UNIVERSITETET I OSLO

INF Puslegruppa - Kom i gang med PusleChat

IN Notat om I/O i Java

Dette er en demonstrasjonsside som vi skal bruke for å se litt nærmere på HTTP protokollen. Eksemplet vil også illustrere et par ting i PHP.

Eks 1: Binærtre Binærtretraversering Eks 2: Binærtre og stakk

INF1010 våren 2018 tirsdag 23. januar

INF Uke 10. Ukesoppgaver oktober 2012

Oblig 4Hybelhus litt mer tips enn i oppgaven

UNIVERSITETET I OSLO

Side 1 av 11, prosesser, tråder, synkronisering, V. Holmstedt, HiO 2006

Forelesning inf Java 4

IN1010 våren januar. Objektorientering i Java

i=0 Repetisjon: arrayer Forelesning inf Java 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker 0*0 0*2 0*3 0*1 0*4

Gjøre noe i hele treet = kalle på samme metode i alle objekten. Java datastruktur Klassestruktur

Forkurs INF1010. Dag 1. Andreas Færøvig Olsen Tuva Kristine Thoresen

Dagens tema: 12 gode råd for en kompilatorskriver

UNIVERSITETET I OSLO

INF1010 våren januar. Objektorientering i Java

UNIVERSITETET I OSLO

I et Java-program må programmøren lage og starte hver tråd som programmet bruker. Er dette korrekt? Velg ett alternativ

UNIVERSITETET I OSLO

2 Om statiske variable/konstanter og statiske metoder.

Introduksjon til objektorientert. programmering. Hva skjedde ~1967? Lokale (og globale) helter. Grunnkurs i objektorientert.

INF1000 EKSTRATILBUD. Stoff fra uke 1-5 (6) 3. oktober 2012 Siri Moe Jensen

Innhold uke 4. INF 1000 høsten 2011 Uke 4: 13. september. Deklarasjon av peker og opprettelse av arrayobjektet. Representasjon av array i Java

Velkommen til. INF våren 2016

Forklaring til programmet AbstraktKontoTest.java med tilhørende filer Konto.java, KredittKonto.java, SpareKonto.java

HØGSKOLEN I SØR-TRØNDELAG

INF1000 (Uke 4) Mer om forgreninger, While-løkker

Installasjonsveiledning Visma Avendo, versjon 5.2

Hvis en person har inntekt < , så betaler han 10% skatt på alt, og ellers betaler han 10% skatt på de første og 30% på resten.

Hvis en person har inntekt < , så betaler han 10% skatt på alt, og ellers betaler han 10% skatt på de første og 30% på resten.

INF 1010, vår 2005 Løsningsforslag uke 11

INF1010 Tråder J. Marit Nybakken Motivasjon. Å lage en tråd

Operativsystemer og grensesnitt

INF1000 Metoder. Marit Nybakken 16. februar 2004

I dag INF1000 (Uke 4) Mer om forgreninger, While-løkker. Tre måter å lese fra terminal. Repetisjon. Mer om forgrening While-løkker

Kapittel 1. Datamaskiner og programmeringsspråk. 1.1 Programmering

Feilmeldinger, brukerinput og kontrollflyt

6107 Operativsystemer og nettverk

Din verktøykasse for anbud og prosjekt

Løse reelle problemer

Oversikt. INF1000 Uke 1 time 2. Repetisjon - Introduksjon. Repetisjon - Program

Programmering Høst 2017

Fra Python til Java. En introduksjon til programmeringsspråkenes verden. Dag Langmyhr

Introduksjon til objektorientert programmering

Lese fra fil. INF1000 : Forelesning 5. Eksempel. De vanligste lesemetodene. Metoder:

INF1000 oppgaver til uke 38 (17 sep 23 sep)

INF1000 : Forelesning 4

INF Obligatorisk innlevering 5

Eksamen i emnet INF100 Grunnkurs i programmering (Programmering I) og i emnet INF100-F Objektorientert programmering i Java I Løsningsforslag

Dagens tema: 12 gode råd for en kompilatorskriver. Sjekking av navn. Lagring av navn. Hvordan finne et navn?

Leksjon 7. Filer og unntak

INF1000 (Uke 15) Eksamen V 04

INF1000 (Uke 15) Eksamen V 04

Drosjesentralen. I-120: Obligatorisk oppgave 2, 2000

UNIVERSITETET I OSLO

Tre måter å lese fra terminal. Java 4. Eksempel. Formatert utskrift til skjerm

I dag INF1000 (Uke 4) Mer om forgreninger, While-løkker. Tre måter å lese fra terminal. Tre måter å lese fra terminal.

Gjennomgang av eksamen H99

En klasse er noe - en metode gjør noe (! / # <= (! * +!! ",-' %. "- -/ %.!#) )! " 0'%! * *$! "1-)) '' % '. 22!'( 7/ /! * 2 2! "*"% 8"%% 9 - -!

1. Finn klassene (hvilke objekter er det i problemet) 1. Dataene som beskriver problemet (hvilke objekter har vi og hvor mange klasser er det?

i=0 i=1 Repetisjon: nesting av løkker INF1000 : Forelesning 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker j=0 j=1 j=2 j=3 j=4

Transkript:

Innlevering LAB 4. Gruppe 4. oppgaver 01.10.2014 Gr.4 Socket programmering Gr.4 1).Test ut programmene Klientmaskin og Tjenermaskin som er gitt. Når bruker "localhost" må begge programmene kjøres på samme maskin. 2).Gjør nødvendige forandringer i Klientmaskin programmet, slik at man kan kjøre programmene på hver sin PC. 3).Gjør nødvendige forandringer i programmene slik at begge PC'ene kan skrive tekst til hverandre. Moretn R. Linstad, Erlend Pettersen, Anh- Thu Nguyen, Oybek Shernazarov, Martin Solberg Todorov

Sockets Programmering i Java Hva er en socket? En stikkontakt er den ene ende-punkt av en to-veis kommunikasjonsforbindelse mellom to programmer som kjører over nettverket. Kjører over nettverket betyr at programmene kjøres på forskjellige datamaskiner, vanligvis omtalt som den lokale og eksterne datamaskiner. Men man kan kjøre de to programmene på samme datamaskin. Slike kommuniserende programmer utgjør en klient / server applikasjon. Serveren implementerer en egen logikk, kalt service. Klientene koble til serveren for å få servert, f.eks. å få noen data eller be om beregningen av enkelte data. Ulike klient / server-applikasjoner gjennomsføre ulike typer tjenester. For å skille mellom forskjellige tjenester, ble en nummereringsforeslått. Denne konvensjonen bruker heltallsantall, kalt portnumre, for å betegne tjenestene. En server å implementere en tjeneste tildeler en bestemt port nummer til poenget med tjenesten oppføring. Det er ingen spesifikk fysiske inngangspunkter for tjenestene i en datamaskin. Portnumrene for tjenestene er lagret i konfigurasjonsfiler og brukes av dataprogram for å lage nettverkstilkoblinger. En socked er en kompleks datastruktur som inneholder en Internett-adresse og et portnummer. En socket, derimot, blir referert til av sin descriptor, som en fil som er referert til av en fil descriptor. Det er derfor, kontaktene er tilgjengelig via et programmeringsgrensesnitt (API) som ligner på filen input / output API. Dette gjør programmeringen av nettverksapplikasjoner svært enkel. De to-veis kommunikasjon kobling mellom de to programmene som kjører på forskjellige datamaskiner gjøres ved å lese fra og skrive til kontaktene som er opprettet på disse datamaskinene. De leses fra en socked data er data skrev inn i den andre kontakten på linken. Og gjensidig, de dataene skrev inn i en stikkontakt i data som leses fra den andre kontakten på linken. Disse to kontakter skapes og knyttes under tilkoblingen etableringen fase. Koblingen mellom to kontakter er som et rør som er implementert ved hjelp av en bunke med protokoller. Denne linkingen av kontaktene innebærer at en intern Inntaket har en mye mer kompleks datastruktur, eller mer presist, en sammenslutning av datastrukturer. Dermed er en socket datastruktur mer enn bare en internett-adresse og et portnummer. Forestille seg en socket som en datastruktur som inneholder minst internettadressen og portnummeret på den lokale datamaskinen, og Internett-adressen og portnummeret på den eksterne datamaskinen. Hvordan en nettverkstilkobling er opprettet? En nettverkstilkobling er initiert av et klientprogram når det skaper en socket for kommunikasjonen med serveren. For å opprette kontakten i Java, kaller klienten Socket konstruktør og passerer serveradresse og den spesifikke serveren portnummeret til den. På dette stadiet serveren må startes på maskinen som har den angitte adressen og lytter etter tilkoblinger på sin bestemte portnummeret. Serveren bruker en bestemt port dedikert kun til å lytte etter forespørsler fra klienter. Det kan ikke bruke denne bestemte port for datakommunikasjon med klienter fordi serveren må være i stand til å akseptere klientens forbindelse til en hvert øyeblikk. Så, er det bestemt port dedikert kun til å lytte etter nye tilkoblingsforespørsler. Tjenersiden socket forbundet med spesifikke port kalles server socket. Når en tilkoblingsforespørsel kommer på denne kontakten fra klientsiden, klienten og serveren etabler en forbindelse. Denne forbindelsen er etablert som følger: 1. Når serveren mottar en tilkoblingsforespørsel på sin spesielle server port, skaper det en ny socket for det og binder et portnummer til det. 2. Det sender det nye portnummeret til kunden å informere det at tilkoblingen er opprettet. 3. Serveren går på nå ved å lytte på to porter: a. den venter på nye innkommende tilkoblingsforespørsler på sin bestemt port, og b. den leser og skriver meldinger på etablerte tilkoblingen (på ny port) med den aksepterte klienten. Serveren kommuniserer med klienten ved å lese fra og skrive til den nye porten. Hvis andre tilkoblings forespørsler ankommer, godtar serveren dem på lignende måte å skape en ny port for hver ny tilkobling. Dermed når som helst øyeblikk, må serveren være i stand til å kommunisere samtidig med mange klienter og å vente på samme tid for innkommende forespørsler på sin spesielle server port. Kommunikasjonen med hver klient gjøres via kontaktene opprettet for hver kommunikasjon. Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 1

SERVER CLIENT,--------------.,--------------.,- accept <--------------------- create `-,- -. read/write <-------------------> read/write `- -' `--------------' `--------------' Den java.net pakken i Java-utviklingsmiljø gir klassen Socket som implementerer klientsiden og klassen Server klasse som implementerer serversiden stikkontakter. Klienten og serveren må bli enige om en protokoll. De må bli enige om språket av informasjonen overføres frem og tilbake gjennom kontakten. Det er to kommunikasjonsprotokoller: strømmen kommunikasjonsprotokoll datagram kommunikasjonsprotokoll Strømmen kommunikasjonsprotokoll er kjent som TCP (transfer kontrollprotokoll). TCP er en forbindelses orientert protokoll. Det fungerer som beskrevet i dette dokumentet. For å kunne kommunisere over TCPprotokollen, må en forbindelse først bli etablert mellom to stikkontakter. Mens en av kontaktene lytter etter en forespørsel om tilkobling (server), den andre ber om en forbindelse (klient). Når de to kontakter er koblet til, kan de brukes til å sende og / eller motta data. Når vi sier "to kontakter er tilkoblet" mener vi det faktum at serveren akseptert en tilkobling. Som det ble forklart ovenfor serveren oppretter en ny lokale kontakt for den nye forbindelsen. Fremgangsmåten av dette nye lokale socket oppfinnelse, men er gjennomsiktig for klienten. Datagram kommunikasjonsprotokoll, kjent som UDP (User Datagram Protocol) er en forbindelsesløs protokoll. Ingen tilkobling er opprettet før du sender dataene. Dataene sendes i en pakke som heter datagram. Den datagram blir sendt som en forespørsel for etablering av en forbindelse. Imidlertid inneholder datagram ikke bare adressene, den inneholder brukerdata også. Når det kommer til målet brukerdataene blir lest av den eksterne applikasjonen og ingen tilkobling er opprettet. Denne protokollen krever at hver gang en datagram er sendt, den lokale kontakten og fjern socket adresser skal også sendes i datagram. Disse adressene sendes i hvert datagram. Den java.net pakken i Java-utviklingsmiljø gir klassen DatagramSocket for programmering datagram kommunikasjon. UDP er en upålitelig protokoll. Det er ingen garanti for at datagrammer vil bli levert i en god ordre til destinasjonen socket. F.eks. en lang tekst, delt inn i flere sider og sendte en side per datagram, kan mottas i en annen rekkefølge. På den andre siden, er en pålitelig protokoll TCP. TCP garanter at sidene vil bli mottatt i den rekkefølgen de sendes. Når man programmerer TCP og UDP-baserte applikasjoner i Java, er ulike typer stikkontakter brukes. Disse kontaktene er implementert i ulike klasser. Klassene Server og Socket implementer TCP basert stikkontakter og klassen DatagramSocket implementerer UDP basert stikkontakter som følger: Stream-kontakten for å lytte etter klientforespørsler (TCP): klassen Server. Stream socket (TCP): klassen Socket. Datagram socket (UDP): klassen DatagramSocket. Se nedover er et dokument viser hvordan man programmere TCP basert klient / server-applikasjoner. UDP orientert programmering dekkes ikke i dokumentet. Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 2

Åpning av en stikkontakt Klientsiden Når du programmerer en klient, må en socket åpnes like nedenfor: Socket MyClient; MyClient = new Socket ("Machine", portnummer); Denne koden må imidlertid bli satt i en prøve / catch-blokken å fange IOException: Socket MyClient; MyClient = new Socket ("Machine", portnummer); catch (IOException e) { hvor Machine er maskinnavnet for å åpne en forbindelse til og Portnumber er portnummeret der serveren å koble til, er å lytte. Når man velger et portnummer, må man huske på at portnumrene i område fra 0 til 1023 er reservert for standardtjenester, som f.eks. e-post, FTP, HTTP, etc. For denne eks. er (chat server) portnummeret bør velges større enn 1023. Tjenersiden Når man programmerer en server, må en server socket lages først, like nedenfor: Server myservice; MyServerice = new Server (portnummer); catch (IOException e) { Serveren socket er dedikert til å lytte til og godta tilkoblinger fra klienter. Etter å ha akseptert en forespørsel fra en klient serveren oppretter en klient socket å kommunisere (sende / motta data) med klienten, like nedenfor: Socket clientsocket = null; servicesocket = MyService.accept (); catch (IOException e) { Nå servere kan sende / motta data til / fra klienter. Siden kontaktene er som fildeskriptorer på send / motta operasjoner blir gjennomført som les / skrive filoperasjoner på input / output bekker. Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 3

Opprette en input stream På klientsiden, kan bruke Datainput klassen til å lage en input stream å motta svar fra serveren: Datainput innspill; input = new Datainput (MyClient.getInputStream ()); catch (IOException e) { Klassen Datainput kan lese tekstlinjer og Java primitive datatyper i en bærbar måte. Det har flere lesemetoder som lest, readchar, readint, readdouble, og readline. Man har til å bruke hvilken som helst funksjon avhengig av hvilken type data som skal motta fra serveren. På serversiden, er Datainput brukes til å motta innspill fra klienten: Datainput innspill; input = new Datainput (servicesocket.getinputstream ()); catch (IOException e) { Lag en output stream På klientsiden, må en output stream bli opprettet for å sende data til serveren kontakt ved hjelp av klassen Print eller Dataoutputstream av java.io pakken: Print utgang; output = new Print (MyClient.getOutputStream ()); catch (IOException e) { Klassen Print implementerer metodene for visning av Java primitive datatyper verdier, som skrive og println metoder. Dessuten kan man ønsker å bruke Dataoutputstream: Dataoutputstream utgang; output = new Dataoutputstream (MyClient.getOutputStream ()); catch (IOException e) { Klassen Dataoutputstream kan skrive Java primitive datatyper; mange av sine metoder skrive et enkelt Java primitive typen til output stream. På serversiden, kan man bruke klassen Print å sende data til klienten. Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 4

Print utgang; output = new Print (servicesocket.getoutputstream ()); catch (IOException e) { Avsluttende stikkontakter Lukke en socked er som å stenge en fil. Du må lukke en stikkontakt når du ikke trenger den lenger. Utgangen og inngangsstrømmer må være lukket også, men før du lukker kontakten. På klientsiden du må lukke input og output bekker og kontakten like nedenfor: output.close (); input.close (); MyClient.close (); catch (IOException e) { På serveren du må lukke input og output bekker og de to kontaktene som følger: output.close (); input.close (); servicesocket.close (); MyService.close (); catch (IOException e) { Vanligvis, på serveren siden man må lukke bare klienten kontakten etter at klienten blir servert. Serveren kontakten holdes åpen så lenge serveren kjører. En ny klient kan koble til serveren på serveren kontakten for å opprette en ny tilkobling, det vil si en ny klient socket. Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 5

En enkel klient / server applikasjon I denne delen presenterer vi en enkel klient / server applikasjon. Klienten Dette er en enkel klient som leser en linje fra standard input og sender det til ekkoet server. Klienten holder deretter lese ut av stikkontakten før den mottar meldingen "Ok" fra serveren. Når den mottar "Ok" melding da det bryter. // Eksempel 23 import java.io.datainputstream; import java.io.printstream; import java.io.bufferedinputstream; import java.io.ioexception; import java.net.socket; import java.net.unknownhostexception; public class Klient { public static void main (String [] args) { Socket clientsocket = null; Datainput er = null; Print os = null; Datainput inputline = null; * Åpne en socket på port 2222. Åpne input og output bekker. clientsocket = new Socket ("localhost", 2222); os = new Print (clientsocket.getoutputstream ()); er = new Datainput (clientsocket.getinputstream ()); inputline = new Datainput (ny BufferedInputStream (System.in)); Catch (UnknownHostException e) { System.err.println ("Vet ikke om host"); Catch (IOException e) { System.err.println ("Kunne ikke få I / O for tilkobling til host"); * Hvis alt er initialisert da ønsker vi å skrive noen data til * Kontakten vi har åpnet en forbindelse til på port 2222. if (clientsocket! = null && os! = null && er! = null) { * Hold på lesing fra / til kontakten til vi får "Ok" fra * Server, når vi fikk det da vi bryte. System.out.println (".. Klienten startet Skriv inn eventuell tekst du vil avslutte det skriver 'OK'."); String responseline; os.println (inputline.readline ()); while ((responseline = is.readline ())! = null) { System.out.println (responseline); if (responseline.indexof ("Ok")! = -1) { Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 6

break; os.println (inputline.readline ()); * Lukk output stream, lukke input stream, lukke kontakten. os.close (); is.close (); clientsocket.close (); Catch (UnknownHostException e) { System.err.println ("Prøver å koble til ukjent vert:" + e); Catch (IOException e) { System.err.println ("IOException:" + e); Serveren. Dette er et enkelt ekko-server. Serveren er dedikert til ekko meldinger mottatt fra kunder. Når den mottar en melding den sender melding tilbake til klienten. Dessuten legger den strengen "fra server:" i fra av ekko meldingen. // Eksempel 24 import java.io.datainputstream; import java.io.printstream; import java.io.ioexception; import java.net.socket; import java.net.serversocket; public class Server { public static void main (String args []) { Server echoserver = null; Streng linje; Datainput er; Print os; Socket clientsocket = null; * Åpne en server socket på port 2222. Merk at vi ikke kan velge en port mindre * Enn 1023 hvis vi ikke er privilegerte brukere (root). echoserver = new Server (2222); Catch (IOException e) { * Lag en socket objekt fra Server å lytte til og akseptere * Tilkoblinger. Åpne input og output bekker. System.out.println (". Serveren startet det på <CTRL> <C> For å stoppe."); Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 7

clientsocket = echoserver.accept (); er = new Datainput (clientsocket.getinputstream ()); os = new Print (clientsocket.getoutputstream ()); Så lenge vi mottar data, ekko at data tilbake til klienten. while (true) { linje = is.readline (); os.println ("fra server:" + linje); Catch (IOException e) { Kompilere og kjøre programmet For å prøve dette programmet du må kompilere de to programmene: Eksempel 23 og Eksempel 24. Lagre disse programmene på datamaskinen. Navngi filene Client.java og Server.java. Åpne et shell vindu på datamaskinen og endre den gjeldende katalogen til katalogen der du lagret disse filene. Skriv inn følgende to kommandoer i skallet vinduet. javac Server.java javac Client.java Hvis Java kompilatoren er installert på datamaskinen, og PATH-variabelen er konfigurert for skallet å finne javac kompilatoren, da disse to kommandolinjer vil opprette to nye filer i gjeldende katalog: filene Server.class og Client.class Start serveren i skallet vinduet ved hjelp av kommandoen: java Server Man vil se følgende melding i dette vinduet Serveren startet. For å stoppe den trykker <CTRL> <C>. forteller at serveren er i gang. Åpne et nytt shell vindu og endre den gjeldende katalogen til katalogen der du lagret programfilene. Starte klienten i skallet vinduet ved hjelp av kommandoen: Java-klient Følgende melding i dette vinduet Klienten startet. Skriv inn hvilken som helst tekst. For å avslutte det skrive "Ok". Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 8

forteller at klienten er i gang. Type, f.eks. teksten Hallo i dette vinduet. Følgende resultat. hallo Fra server: hello forteller at meldingen Hei ble sendt til serveren og ekkoet ble mottatt av kunden fra serveren. En multi-threaded Client / Server-programmet Neste eksempel er en chat program. En chat-programmet består av en prat server og en chat-klient. Serveren godtar tilkoblinger fra klienter og leverer alle meldinger fra hver klient til andre klienter. Dette er et verktøy for å kommunisere med andre personer over Internett i sanntid. Klienten er implementert ved hjelp av to tråder - en tråd til å samhandle med serveren og den andre med standard input. To tråder er nødvendig fordi en klient må kommunisere med serveren og samtidig må det være klar til å lese meldingene fra standard input som skal sendes til serveren. Serveren er implementert ved hjelp av tråder også. Den bruker en separat tråd for hver forbindelse. Den gyter en ny klient tråd hver gang en ny forbindelse fra en klient er akseptert. Dette forenkler mye utformingen av serveren. Multi-threading, derimot, skaper synkroniseringsproblemer. Vi vil presentere to implementeringer av chat-serveren. En implementering som fokus på multi-threading uten å vurdere synkroniseringsproblemer vil bli presentert først. Da vil vi fokusere på de synkroniseringsproblemer som en multi-threaded implementering skaper. Til slutt, er en oppdatert versjon av multi-threaded chat server som løser synkroniseringsproblemer presentert. Praten Client Koden nedenfor er multi-threaded chat-klient. Den bruker to tråder: en for å lese data fra standard input og sendte det til serveren, den andre til å lese data fra serveren og for å skrive den ut på standard output. // Eksempel 25 import java.io.datainputstream; import java.io.printstream; import java.io.bufferedreader; import java.io.inputstreamreader; import java.io.ioexception; import java.net.socket; import java.net.unknownhostexception; public class MultiThreadChatClient implementerer kjørbart { // Klienten socket private static Socket clientsocket = null; // Output stream private static Print os = null; // Input stream private static Datainput er = null; private static BufferedReader inputline = null; private static boolean lukket = false; public static void main (String [] args) { Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 9

// Standardporten. int portnummer = 2222; // Standard verts. String host = "localhost"; if (args.length <2) { System.out.println ("Bruk: java MultiThreadChatClient <verts> <portnummer> \ n" + "Nå bruker host =" + host + ", portnummer =" + portnummer); Else { host = args [0]; portnummer = Integer.valueOf (args [1]) intvalue ().; * Åpne en stikkontakt på en gitt vert og port. Åpne input og output bekker. clientsocket = new Socket (host, portnummer); inputline = new BufferedReader (ny InputStreamReader (System.in)); os = new Print (clientsocket.getoutputstream ()); er = new Datainput (clientsocket.getinputstream ()); Catch (UnknownHostException e) { System.err.println ("Vet ikke om host" + host); Catch (IOException e) { System.err.println ("Kunne ikke få I / O for tilkobling til verts" + Host); * Hvis alt er initialisert da ønsker vi å skrive noen data til * Kontakten vi har åpnet en forbindelse til på babord portnummer. if (clientsocket! = null && os! = null && er! = null) { Lag en tråd for å lese fra serveren. ny tråd (nye MultiThreadChatClient ()) start ().; while (! lukket) { os.println (inputline.readline () trim ().); * Lukk output stream, lukke input stream, lukke kontakten. os.close (); is.close (); clientsocket.close (); Catch (IOException e) { System.err.println ("IOException:" + e); * Lag en tråd for å lese fra serveren. (Non-Javadoc) * *see Java.lang.Runnable # run () public void run () { Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 10

* Hold på lesing fra socket till får vi "Bye" fra * Server. Når vi fikk det da vi ønsker å bryte. String responseline; while ((responseline = is.readline ())! = null) { System.out.println (responseline); if (responseline.indexof ("*** Bye")! = -1) break; Lukket = true; Catch (IOException e) { System.err.println ("IOException:" + e); Chat-serveren Vi fortsetter med multi-threaded chat server. Den bruker en egen tråd for hver klient. Den gyter en ny klient tråd hver gang en ny forbindelse fra en klient er akseptert. Denne tråden åpner input og output bekker for en bestemt klient, det spør klientens navn, informerer alle klienter om det faktum at en ny klient har sluttet seg til chat-rom og, så lenge det mottar data, echos at data tilbake til alle andre kunder. Når klienten forlater chatterom, informerer denne tråden også kunder om at og avsluttes. // Eksempel 26 import java.io.datainputstream; import java.io.printstream; import java.io.ioexception; import java.net.socket; import java.net.serversocket; * En chat-server som leverer offentlige og private meldinger. public class MultiThreadChatServer { // Serveren socket. private static Serverserver = null; // Klienten socket. private static Socket clientsocket = null; // Denne chat-server kan godta opptil maxclientscount klienters tilkoblinger. private static final int maxclientscount = 10; private statiske endelige clientthread [] tråder = new clientthread [maxclientscount]; public static void main (String args []) { // Standard portnummer. int portnummer = 2222; if (args.length <1) { System.out.println ("Bruk: java MultiThreadChatServer <portnummer> \ n" + "Nå bruker portnummer =" + portnummer); Else { portnummer = Integer.valueOf (args [0]) intvalue ().; Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 11

* Åpne en server socket på portnummer (standard 2222). Legg merke til at vi kan * Ikke velge en port mindre enn 1023 hvis vi ikke er privilegerte brukere (root). Server = new Server (portnummer); Catch (IOException e) { * Lag en klient socket for hver tilkobling og gi det til en ny klient * Tråden. while (true) { clientsocket = serversocket.accept (); int i = 0; for (i = 0; i <maxclientscount; i ++) { if (tråder [i] == null) {. (Tråder [i] = new clientthread (clientsocket, tråder)) start (); break; if (i == maxclientscount) { Print os = new Print (clientsocket.getoutputstream ()); os.println (". Server for opptatt Prøv senere."); os.close (); clientsocket.close (); Catch (IOException e) { * Den chat-klient tråden. Denne klienten tråden åpner input og output * Bekker for en bestemt klient, spør klientens navn, informerer alle * Klienter koblet til serveren om det faktum at en ny klient har sluttet * Chatterommet, og så lenge den mottar data, echos at data tilbake til alle * andre klienter. Når en klient forlater chatterom denne tråden informerer også * Alle kunder om at og avsluttes. klasse clientthread strekker Thread { Privat Datainput er = null; Privat Print os = null; Privat Socket clientsocket = null; private endelige clientthread [] tråder; private int maxclientscount; offentlig clientthread (Socket clientsocket, clientthread [] tråder) { this.clientsocket = clientsocket; this.threads = tråder; maxclientscount = threads.length; Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 12

public void run () { int maxclientscount = this.maxclientscount; clientthread [] tråder this.threads; * Lag input og output bekker for denne klienten. er = new Datainput (clientsocket.getinputstream ()); os = new Print (clientsocket.getoutputstream ()); os.println ("Skriv inn navnet ditt."); String navn = is.readline () trim ().; os.println ("Hei" + navn + "Til vår chat room \ nfor å forlate Skrive / sluttet i en ny linje."); if (tråder [i]! = null && tråder [i]! = dette) { tråder [i].os.println ("*** En ny bruker" + navn + "Kom inn i chatterommet!!! ***"); while (true) { String linje = is.readline (); if (line.startswith ("/ quit")) { break; if (tråder [i]! = null) { tråder [i].os.println ("<" + navn + "og gr;" + linje); if (tråder [i]! = null && tråder [i]! = dette) { tråder [i].os.println ("*** Den bruker" + navn + "Er å forlate chatrommet!!! ***"); os.println ("*** Bye" + navn + "***"); * Rydd opp. Sett gjeldende tråd variabel til null, slik at en ny klient * Kunne bli godkjent av serveren. if (tråder [i] == denne) { tråder [i] = null; * Lukk output stream, lukke input stream, lukke kontakten. is.close (); os.close (); clientsocket.close (); Catch (IOException e) { Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 13

Synkroniserings utgaver av multi-threaded chat server gjennomføring Tenk nå synkroniseringsproblemer en slik implementering skaper. For å forenkle vår oppgave la oss dele chat serverkoden som følger, se partisjonert koden under. // Eksempel 26 import java.io.datainputstream; import java.io.printstream; import java.io.ioexception; import java.net.socket; import java.net.serversocket; * En chat-server som leverer offentlige og private meldinger. public class MultiThreadChatServer { // Serveren socket. private static Serverserver = null; // Klienten socket. private static Socket clientsocket = null; // Denne chat-server kan godta opptil maxclientscount klienters tilkoblinger. private static final int maxclientscount = 10; private statiske endelige clientthread [] tråder = new clientthread [maxclientscount]; public static void main (String args []) { 1 // Standard portnummer. int portnummer = 2222; if (args.length <1) { System.out.println ("Bruk: java MultiThreadChatServer <portnummer> \ n" + "Nå bruker portnummer =" + portnummer); Else { portnummer = Integer.valueOf (args [0]) intvalue ().; * Åpne en server socket på portnummer (standard 2222). Legg merke til at vi kan * Ikke velge en port mindre enn 1023 hvis vi ikke er privilegerte brukere (root). Server = new Server (portnummer); Catch (IOException e) { * Lag en klient socket for hver tilkobling og gi det til en ny klient * Tråden. while (true) { Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 14

2 clientsocket = serversocket.accept (); int i = 0; for (i = 0; i <maxclientscount; i ++) { if (tråder [i] == null) {. (Tråder [i] = new clientthread (clientsocket, tråder)) start (); break; if (i == maxclientscount) { Print os = new Print (clientsocket.getoutputstream ()); os.println (". Server for opptatt Prøv senere."); os.close (); clientsocket.close (); Catch (IOException e) { * Den chat-klient tråden. Denne klienten tråden åpner input og output * Bekker for en bestemt klient, spør klientens navn, informerer alle * Klienter koblet til serveren om det faktum at en ny klient har sluttet * Chatterommet, og så lenge den mottar data, echos at data tilbake til alle * andre klienter. Når en klient forlater chatterom denne tråden informerer også * Alle kunder om at og avsluttes. klasse clientthread strekker Thread { 3 Privat Datainput er = null; Privat Print os = null; Privat Socket clientsocket = null; private endelige clientthread [] tråder; private int maxclientscount; offentlig clientthread (Socket clientsocket, clientthread [] tråder) { this.clientsocket = clientsocket; this.threads = tråder; maxclientscount = threads.length; public void run () { int maxclientscount = this.maxclientscount; clientthread [] tråder this.threads; * Lag input og output bekker for denne klienten. er = new Datainput (clientsocket.getinputstream ()); os = new Print (clientsocket.getoutputstream ()); os.println ("Skriv inn navnet ditt."); String navn = is.readline () trim ().; os.println ("Hei" + navn + "Til vår chat room \ nfor å forlate Skrive / sluttet i en ny linje."); 4 Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 15

5 6 7 8 9 10 11 if (tråder [i]! = null && tråder [i]! = dette) { tråder [i].os.println ("*** En ny bruker" + navn + "Kom inn i chatterommet!!! ***"); while (true) { String linje = is.readline (); if (line.startswith ("/ quit")) { break; if (tråder [i]! = null) { tråder [i].os.println ("<" + navn + ">" + linje); if (tråder [i]! = null && tråder [i]! = dette) { tråder [i].os.println ("*** Den bruker" + navn + "Er å forlate chatrommet!!! ***"); os.println ("*** Bye" + navn + "***"); * Rydd opp. Sett gjeldende tråd variabel til null, slik at en ny klient * Kunne bli godkjent av serveren. if (tråder [i] == denne) { tråder [i] = null; * Lukk output stream, lukke input stream, lukke kontakten. is.close (); os.close (); clientsocket.close (); Catch (IOException e) { Siden alle tråder kjørt samtidig, er tilgangen til denne tabellen også sammenfallende. Anta nå at en gjenge (gjenge 1) kommer inn i delen 4, mens en annen tråd (tråd 2) går inn i den delen 10 av koden. Seksjonen 4 bruker tabell trådene [] for å informere kundene om en ny klient. Den 10, men fjerner fra denne matrisen tråden referanser til klienten som forlater chatterom. Det kan skje, at en tråder [i] referanse, samtidig som brukes i 4 er satt til null i 10 av en annen tråd - ved tråden av klienten forlate chatrommet. Tabellen nedenfor viser dette scenariet. I dette scenariet Gjenger 1 utfører hvis setningen i del 4. Anta tråder [i] ikke er null i dette øyeblikk. Anta også, gjenge 1 blir avbrutt av operativsystemet umiddelbart etter evaluering hvis setningen tilstand. Det betyr, gjenge 1 er satt i en ventekøen, mens Gjenger 2 starter utførende del 10. Slike type kjøring kalles inter-levende. Anta, Tråd 2 sett tråder [i] til null ved utføring del 10. Til slutt, er tråd en gjenopptatt og utfører tråder [i].os.println () uttalelse. Men tråder [i] er null på dette øyeblikk. Dette vil føre til en nullpeker unntak. Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 16

Dette unntaket vil stenge unormalt i forbindelse med en klient. Og alle som på grunn av en annen klient som bestemte seg for å forlate chatrommet. Den samme situasjonen kan oppstå hvis vi vurdere samtidighet av noen av seksjonen 2,6,8 med 10. Slike situasjoner er ikke akseptabelt og må løses på riktig måte i en samtidig multithreaded program. 4 10 4 Gjenger 1 Gjenger 2 if (tråder [i]! = null && tråder [i]! = dette) { tråder [i].os.println ("*** En ny bruker" + navn + "Kom inn i chatterommet!!! ***"); if (tråder [i] == denne) { tråder [i] = null; For å unngå en slik type unntak, må trådene være synkronisert slik at de utfører de kritiske deler av koden (grønt) i sekvens, og således uten å inter-levende. F.eks. i tabellen nedenfor, er utføringen av de to deler av kodesekvens - de kritiske delene utføres uten avbrytelse. Vi kaller en slik utførelse synkronisert. Arkivere denne synkroniseringen må vi bruke den synkroniserte (denne) { uttalelse, som nedenfor. 4 10 Gjenger 1 Gjenger 2 synkronisert (denne) { if (tråder [i]! = null && tråder [i]! = dette) { tråder [i].os.println ("*** En ny bruker" + navn + "Kom inn i chatterommet!!! ***"); synkronisert (denne) { if (tråder [i] == denne) { tråder [i] = null; Alle synkroniserte (denne) { uttalelser utelukker gjensidig hverandre. Det betyr, at når en tråd går inn i synkronisert (denne) { statement det bekrefter først at enhver annen synkronisert (denne) { uttalelsen ikke blir utført av en annen tråd. Hvis en slik uttalelse blir henrettet i en tynn tråd, så denne tråden, samt alle andre tråder prøver å utføre en synkronisert (denne) { uttalelse, blir tvunget til å vente helt til tråden utfører de synkroniserte (denne) { opphører dette utsagnet. Når tråden utfører en synkronisert (denne) { uttalelse forlater den kritiske delen, er at når det avslutter synkronisert (denne) { uttalelse, en tråd venter på kritiske delen går inn i sitt synkronisert (denne) {. Når en tråd går inn synkronisert (denne) { uttalelse den blokkerer alle andre tråder fra å komme inn sine synkronisert (denne) { uttalelser. Dermed setter alle kritiske deler i synkronisert (denne) { uttalelser vi guaran at chat-serveren vil utføre korrekt uten stigende nullpeker unntak forårsaket av samtidig gjennomføring av andre kritiske deler. Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 17

Den synkronisert (denne) { uttalelsen er et kraftig verktøy. Men ved å bruke det krever en god forståelse av synkroniserings problemet. Feil bruk av synkronisert (denne) { uttalelse kan føre til vranglås av programmet. En vranglås er et scenario når en tråd venter på en annen tråd til å forlate sin kritiske delen alltid. For å forklare dette scenariet antar vi utvidet den kritiske punkt 6 som nedenfor. Dette er, antar at den synkronisert (denne) { setningen inneholder en løkke som potensielt kan utføre for alltid. 6 synkronisert (denne) { while (true) { String linje = is.readline (); if (line.startswith ("/ quit")) { break; if (tråder [i]! = null) { tråder [i].os.println ("<" + navn + ">" + linje); Anta at "/ quit" kommando aldri kommer eller det kommer etter en svært lang tid. Tråden utfører denne sløyfen inne i synkronisert (denne) { uttalelsen vil blokkere alle andre tråder fra å utføre sine synkronisert kode fordi de vil vente på sine synkronisert (denne) { uttalelser. F.eks. vil den delen av koden i rødt (se nedenfor) skal aldri utføres etter tråd 2, hvis Gjenger 1 kom inn i while (true) loop og forblir i evig. 6 10 Gjenger 1 Gjenger 2 synkronisert (denne) { while (true) { String linje = is.readline (); if (line.startswith ("/ quit")) { break; if (tråder [i]! = null) { tråder [i].os.println ("<" + navn + ">" + linje); synkronisert (denne) { if (tråder [i] == denne) { tråder [i] = null; Så når du synkroniserer programmer, en hensiktsmessig løsning må iverksettes for å løse slike problemer, ellers synkronisert (denne) { uttalelse kan føre til svært lange forsinkelser og til og med vranglåser. Unngå å sette unødvendige synkronisert (denne) { uttalelser i programmet. F.eks. er det ikke nødvendig å synkronisere den del 2 av koden (se tabellen på partisjonert kode). Selv om denne kode modifiserer tråder [] array, en bedre kontroll av koden oppdager at det ikke er noen risiko for denne modifikasjon vil skape nullpeker unntak eller andre problemer i programmet. Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 18

Den synkroniserte versjon av chat-server I denne delen presenterer vi den oppdaterte versjonen av chat-serveren som løser synkroniseringsproblemer er beskrevet i forrige avsnitt. Den synkronisert (denne) { påstanden brukes for å løse synkroniseringsproblemer. Også denne versjonen av chat-server er forbedret for å levere private meldinger til kunder. // Eksempel 26 (oppdatert) import java.io.datainputstream; import java.io.printstream; import java.io.ioexception; import java.net.socket; import java.net.serversocket; * En chat-server som leverer offentlige og private meldinger. public class MultiThreadChatServerSync { // Serveren socket. private static Serverserver = null; // Klienten socket. private static Socket clientsocket = null; // Denne chat-server kan godta opptil maxclientscount klienters tilkoblinger. private static final int maxclientscount = 10; private statiske endelige clientthread [] tråder = new clientthread [maxclientscount]; public static void main (String args []) { // Standard portnummer. int portnummer = 2222; if (args.length <1) { System.out.println ("Bruk: java MultiThreadChatServerSync <portnummer> \ n" + "Nå bruker portnummer =" + portnummer); Else { portnummer = Integer.valueOf (args [0]) intvalue ().; * Åpne en server socket på portnummer (standard 2222). Legg merke til at vi kan * Ikke velge en port mindre enn 1023 hvis vi ikke er privilegerte brukere (root). Server = new Server (portnummer); Catch (IOException e) { * Lag en klient socket for hver tilkobling og gi det til en ny klient * Tråden. while (true) { clientsocket = serversocket.accept (); int i = 0; for (i = 0; i <maxclientscount; i ++) { Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 19

if (tråder [i] == null) {. (Tråder [i] = new clientthread (clientsocket, tråder)) start (); break; if (i == maxclientscount) { Print os = new Print (clientsocket.getoutputstream ()); os.println (". Server for opptatt Prøv senere."); os.close (); clientsocket.close (); Catch (IOException e) { * Den chat-klient tråden. Denne klienten tråden åpner input og output * Bekker for en bestemt klient, spør klientens navn, informerer alle * Klienter koblet til serveren om det faktum at en ny klient har sluttet * Chatterommet, og så lenge den mottar data, echos at data tilbake til alle * andre klienter. Tråden kringkaste innkommende meldinger til alle klienter og * Ruter privat melding til den aktuelle klienten. Når en klient forlater * Chatterom denne tråden informerer også alle kunder om at og avsluttes. klasse clientthread strekker Thread { private String korrespondanse = null; Privat Datainput er = null; Privat Print os = null; Privat Socket clientsocket = null; private endelige clientthread [] tråder; private int maxclientscount; offentlig clientthread (Socket clientsocket, clientthread [] tråder) { this.clientsocket = clientsocket; this.threads = tråder; maxclientscount = threads.length; public void run () { int maxclientscount = this.maxclientscount; clientthread [] tråder this.threads; * Lag input og output bekker for denne klienten. er = new Datainput (clientsocket.getinputstream ()); os = new Print (clientsocket.getoutputstream ()); String navn; while (true) { os.println ("Skriv inn navnet ditt."); name = is.readline () trim ().; if (name.indexof ('@') == -1) { break; Else { Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 20

os.println ("Navnet bør ikke inneholde '@' karakter."); Velkommen den nye klienten. os.println ("Welcome" + navn + ". Til vår chat room \ nfor å forlate Skrive / sluttet i en ny linje."); synkronisert (denne) { if (tråder [I]! = null && tråder [i] == denne) { korrespondanse = "@" + navn; break; if (tråder [i]! = null && tråder [i]! = dette) { tråder [i].os.println ("*** En ny bruker" + navn + "Kom inn i chatterommet!!! ***"); Begynn samtalen. while (true) { String linje = is.readline (); if (line.startswith ("/ quit")) { break; Hvis meldingen private sendte den til gitt klient. if (line.startswith ("@")) { String [] ord = line.split ("\\ S", 2); if (words.length> 1 && ord [1]! = null) { ord [1] = ord [1].trim (); if (! ord [1].isEmpty ()) { synkronisert (denne) { if (tråder [i]! = null && tråder [i]! = dette && Tråder [i].clientname! = Null && Tråder [i].clientname.equals (ord [0])) { tråder [i].os.println ("<" + navn + ">" + ord [1]); * Echo denne meldingen for å la kunden vet det private * Meldingen ble sendt. this.os.println (">" + navn + ">" + ord [1]); break; Else { Meldingen er offentlig, kringkaste det til alle andre kunder. synkronisert (denne) { if (tråder [I]! = null && tråder [i].clientname! = null) { tråder [i].os.println ("<" + navn + ">" + linje); Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 21

synkronisert (denne) { if (tråder [i]! = null && tråder [i]! = dette && tråder [i].clientname! = null) { tråder [i].os.println ("*** Den bruker" + navn + "Er å forlate chatrommet!!! ***"); os.println ("*** Bye" + navn + "***"); * Rydd opp. Sett gjeldende tråd variabel til null, slik at en ny klient * Kunne bli godkjent av serveren. synkronisert (denne) { if (tråder [i] == denne) { tråder [i] = null; * Lukk output stream, lukke input stream, lukke kontakten. is.close (); os.close (); clientsocket.close (); Catch (IOException e) { Kompilere og kjøre programmet For å prøve dette programmet må kompilere de to programmene: Eksempel 25 og Eksempel 26 (oppdatert). Lagre disse programmene på datamaskinen. Navngi filene MultiThreadChatClient.java og MultiThreadChatServerSync.java. Åpne et shell vindu på datamaskinen og endre den gjeldende katalogen til katalogen der du lagret disse filene. Skriv inn følgende to kommandoer i skallet vinduet. javac MultiThreadChatServerSync.java javac MultiThreadChatClient.java Hvis Java kompilatoren er installert på datamaskinen, og PATH-variabelen er konfigurert for skallet å finne javac kompilatoren, da disse to kommandolinjer vil opprette to nye filer i gjeldende katalog: filene MultiThreadChatServerSync.class og MultiThreadChatClient.class Start serveren i skallet vinduet ved hjelp av kommandoen: java MultiThreadChatServerSync Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 22

Følgende melding i dette vinduet Bruk: java MultiThreadChatServerSync <portnummer> Nå bruker portnummer = 2222 forteller at chat-server er startet og at den lytter etter tilkoblinger på port nummer 2222. Uttrykket Bruk: java MultiThreadChatServerSync <portnummer> forteller at man kan starte serveren oppgi en parameter - portnummeret. Som standard er imidlertid porten 2222 som brukes. Åpne et nytt shell vindu og endre den gjeldende katalogen til katalogen der lagret programfilene. Starte klienten i skallet vinduet ved hjelp av kommandoen: java MultiThreadChatClient Følgende melding i dette vinduet Bruk: java MultiThreadChatClient <verts> <portnummer> Nå bruker host = localhost, portnummer = 2222 Skriv inn navnet ditt. forteller at klienten er i gang. Type, f.eks. navnet Anonymous1 i dette vinduet. Følgende resultat. Hei Anonymous1 til vår chat room. Å forlate inn / sluttet i en ny linje forteller at klienten Anonymous1 kom inn i chatterommet. Den forteller også at å slutte chatrommet kunden må taste inn / avslutte kommandoen. Åpne ett skall vinduet og endre den gjeldende katalogen til katalogen der du lagret programfilene. Start en ny klient i skallet vinduet ved hjelp av kommandoen: java MultiThreadChatClient Følgende melding i dette vinduet Bruk: java MultiThreadChatClient <verts> <portnummer> Nå bruker host = localhost, portnummer = 2222 Skriv inn navnet ditt. forteller at klienten er i gang. Nå har to klienter som er koblet til serveren. Type, f.eks. tekst Anonymous2 i dette vinduet. Følgende resultat. Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 23

Hei Anonymous2 til vår chat room. Å forlate inn / sluttet i en ny linje forteller at klienten Anonymous2 kom inn i chatterommet. Den forteller også at å slutte chatrommet kunden må taste inn / avslutte kommandoen. I vinduet til klienten Anonymous1 følgende melding vil bli skrevet ut. *** En ny bruker Anonymous2 kom inn i chatterommet!!! *** Hvis går inn i nå en melding i noen av klientvinduet meldingen vil bli trykt også i vinduet på den andre klienten. Denne typen meldingsutveksling er en chat-økt. Et eksempel chat Nedenfor viser vi et mulig scenario av en chat mellom de to klienter. Chat-klient Anonymous1 $ Java MultiThreadChatClient Bruk: java MultiThreadChatClient Nå bruker host = localhost, portnummer = 2222 Skriv inn navnet ditt. Anonymous1 Hei Anonymous1 til vår chat room. Å forlate inn / sluttet i en ny linje *** En ny bruker Anonymous2 kom inn i chatterommet!!! *** Hei Anonymous2 <Anonymous1> Hei Anonymous2 Chat-klient Anonymous2 $ Java MultiThreadChatClient Bruk: java MultiThreadChatClient Nå bruker host = localhost, portnummer = 2222 Skriv inn navnet ditt. Anonymous2 Hei Anonymous2 til vår chat room. Å forlate inn / sluttet i en ny linje <Anonymous1> Hei Anonymous2 Hi Anonymous1 <Anonymous2> Hei Anonymous1 <Anonymous2> Hei Anonymous1 Hvordan har du det? <Anonymous1> Hvor er du? <Anonymous1> Hvor er du? <Anonymous2> Jeg er godt Jeg er godt <Anonymous2> Jeg er godt Og du? <Anonymous2> Og du? Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 24

<Anonymous2> Og du? Jeg er fint. <Anonymous1> jeg er fint. <Anonymous1> jeg er fint. <Anonymous2> Bye Bye Anonymous2 <Anonymous1> Bye Anonymous2 Bye <Anonymous2> Bye <Anonymous1> Bye Anonymous2 *** Brukeren Anonymous2 forlater chatterom!!! *** / Quit *** Bye Anonymous1 *** / Quit *** Bye Anonymous2 *** Konklusjoner Java sockets API (Socket og Server klasser) er et kraftig og fleksibelt grensesnitt for nettverk programmering av klient / server-applikasjoner. På den annen side, er Java-tråder annen kraftig programmerings rammeverk for klient / server-applikasjoner. Multi-threading forenkler implementering av komplekse klient / server-applikasjoner. Men introduserer det synkroniseringsproblemer. Disse problemene er forårsaket av samtidig utførelse av kritiske deler av programmet ved forskjellige tråder. Den synkronisert (denne) { uttalelse tillater oss å synkronisere gjennomføringen av de kritiske deler. Ved hjelp av dette utsagnet, men krever en god forståelse av synkroniseringsproblemer. Feil bruk av synkronisert (denne) { uttalelse kan føre til andre problemer, f.eks. vranglåser og / eller dårligere ytelse av programmet. Datakommunikasjon LAB4 Innlevering Gr.4 Side nr.: 25