Gå til innhold

Klient-Server, to veis kommunikasjon


Anbefalte innlegg

Skrevet

For å lære java.net tenkte jeg å lage en chatteapplikasjon (en server, flere klienter) benytter Object(In/Out)putstream over Socket for å kommunisere mellom klient og server. Er det noen måte å få til toveis kommunikasjon mellom klient og server?

 

Altså, alle eksemplene jeg har sett (mulig jeg har missforstått dem alle) har vært bygd opp på den måten at klienten sender en melding, og venter på svar fra serveren. Jeg ønsker at klienten skal kunne sende flere meldinger på rad til serveren, uten nødvendigvis å få svar, og serveren skal kunne få "pushe" meldinger til klienten, som skal vises på klientens skjerm, uansett hva klienten holder på med i øyeblikket.

 

Er det noen fikse løsninger på dette, annet enn at klienten regelmessig sender en NOOP-type melding til serveren for å be om at det som evt. ligger i bufferen på serveren skal sendes?

Videoannonse
Annonse
Skrevet
Ja, men hvordan får man to tråder til å jobbe på samme socket?

5240334[/snapback]

 

Du lar en tråd jobbe med referansen til en socket i en synkronisert metode. Så når den tråden har kjørt ferdig, får neste tråd tilgang til metoden.

Skrevet
Blir ikke tråden for inkommende trafikk stående å hindre den andre i å noen gang få tilgang på den synkroniserte metoden?

5244229[/snapback]

Du er ikke nødvendigvis nødt til å kjøre det over samme socket. Dersom du benytter to socketer, så kan du herje så mye du vil, men det vil gjøre det litt vanskeligere å sørge for at ting er i sync i begge ender. Selv om du kanskje vil ha en liten ytelsesforbedring ved å ikke bruke synchronized-metoder, vil jeg ikke tro det er verd strevet (chat-applikasjoner, mer eller mindre uavhengig av protokoll, krever så lite av både båndbredde og prosesseringskraft at det er egentlig ikke verd å ta det i betraktning).

Skrevet (endret)

Jeg fant en tråd som kommer med en fiks løsning på dette problemet. Sliter litt med å forstå at det kan virke.

sendThread = new Thread(new Runnable() {
 public void run() {
   runSend();
 }
},"Send."+name );

 

Ante f.x ikke at man kunne bruke "new INTERFACE()"

Eller sette en variabel lik en helt ny klasse definisjon.

 

Hvis man tenker i litt større sammenheng.. Klient applikasjonene her utveksler kun tekstmeldinger. Dersom de skulle utveksle litt større data, f.x tale eller video.

Jeg getter da på at man bytter ut

in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));

med

in = new ObjectInputStream(sock.getInputStream());
out = new ObjectOutputStream(sock.getOutputStream());

Også sender man en eller annen form for selvlaget klasse fram og tilbake.

Hvor feilsikkert blir et sånt system? TCP skal jo i utgangspunktet garantere at pakker som skades underveis i nettet sendes på nytt, men likevel forekommer bitfeil (f.x man-in-the-middle-attack). Kan det medføre at ObjectInputStream kommer ut av sync, og må ha en reset før den igjen er i stand til å gjenkjenne objekter?

Er det noe som sjekker om objekter har blitt skadet, eller må implementeringen av Serializable-metodene i objektet som sendes ta seg av slikt?

 

Edit: Sett at trafikken blir stor - burde man kjøre hver Socket på serveren som en egen tråd, i tillegg til inn- og utkøene?

Endret av petterg
Skrevet (endret)
Jeg fant en tråd som kommer med en fiks løsning på dette problemet. Sliter litt med å forstå at det kan virke.

sendThread = new Thread(new Runnable() {
 public void run() {
   runSend();
 }
},"Send."+name );

 

Ante f.x ikke at man kunne bruke "new INTERFACE()"

Eller sette en variabel lik en helt ny klasse definisjon.

Google etter 'anonymous inner class'. Dette er en temmelig vanlig konstruksjon, bla.a. til event-håndtering. Selv pleier jeg å gi lese/skrive-trådene mine en vanlig klassedefinisjon (hver), men dette kan sikkert fungere.

 

Hvis man tenker i litt større sammenheng..  Klient applikasjonene her utveksler kun tekstmeldinger. Dersom de skulle utveksle litt større data, f.x tale eller video.

Jeg getter da på at man bytter ut

in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));

med

in = new ObjectInputStream(sock.getInputStream());
out = new ObjectOutputStream(sock.getOutputStream());

Også sender man en eller annen form for selvlaget klasse fram og tilbake.

Tror ikke sending av serialiserte objekter egner seg til annet enn eksempler, nei. :)

 

Ikke så veldig effektivt, så hold deg til (buffered) streams for f.eks. filoverføring.

 

Hvor feilsikkert blir et sånt system? TCP skal jo i utgangspunktet garantere at pakker som skades underveis i nettet sendes på nytt, men likevel forekommer bitfeil (f.x man-in-the-middle-attack).

TCP gir vel rimelig god beskyttelse mot overføringsfeil, og det er litt sjekksumming innebygd i protokollen mener jeg.

Ellers kan du selvsagt gjøre en eller annen form for sjekksum/hash/message digest på dataene før og etter sending, og se om resultatet blir det samme.

 

Om du er redd for mitm-angrep og vil ha sikker overføring, så skulle det være masser av krypto-litteratur på nettet.

 

Edit: Sett at trafikken blir stor - burde man kjøre hver Socket på serveren som en egen tråd, i tillegg til inn- og utkøene?

5248768[/snapback]

Enkleste måte å lage en klient-server-applikasjon på er nok å kjøre to tråder pr. socket, en som leser og en som skriver. Dette bør skalere greit nok opp til ihvertfall 100-200 connections.

Skal serveren betjene drastisk flere sockets må du over på multiplexed/asynkron io, som i Java kan gjøres med java.nio.* -pakkene. Trenger ikke bekymre deg om dem med det første..

Endret av Frank2004

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...