Toon posts:

[Java] verschillende vragen ivm sockets

Pagina: 1
Acties:

Verwijderd

Topicstarter
ik ga een client server programmaatje maken,
ik heb echter wel enkele vragen die ik nie direct terugvindt

a. als ik een string doorstuur naar een socket, kom die aan de ander kant ook enkel en alleen aan als die lijn
dus kan ik er dan zeker van zijn dat als ikde lijn inlees dat de volledige lijn is (althans als er niets misliep)
b. is er een limiet op de lengte van de door te sturen string?
c. het wordt een multithreaded server
maar de verschillende sockets onderling moeten wel aan elkaar aankunnen,
als ik de sockets dan gewoon in een thread gooi, kan ik er dus niet meer aan,
hoe los ik dit op
een private array van sockets voorzien en daar iedere nieuwe connectie insteken?

alvast bedankt

Verwijderd

Verwijderd schreef op 29 september 2002 @ 16:42:
a. als ik een string doorstuur naar een socket, kom die aan de ander kant ook enkel en alleen aan als die lijn dus kan ik er dan zeker van zijn dat als ikde lijn inlees dat de volledige lijn is (althans als er niets misliep)
Ik snap de zin niet helemaal, maar TCP zorgt er wel voor dat een string aankomt zoals jij hem verstuurde.
b. is er een limiet op de lengte van de door te sturen string?
Volgens mij niet. Je kunt een string versturen zolang Java die aankan.
c. het wordt een multithreaded server maar de verschillende sockets onderling moeten wel aan elkaar aankunnen, als ik de sockets dan gewoon in een thread gooi, kan ik er dus niet meer aan, hoe los ik dit op een private array van sockets voorzien en daar iedere nieuwe connectie insteken?
Ehm, als ik goed begrijp wat je bedoelt, kan dat met een array lijkt me. Misschien is een ArrayList vestandiger omdat je nooit van te voren weet hoeveel connecties je binnen zult krijgen.

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Verwijderd schreef op 29 september 2002 @ 16:54:
Ik snap de zin niet helemaal, maar TCP zorgt er wel voor dat een string aankomt zoals jij hem verstuurde.
Dat is niet helemaal waar :)
Wel als je de ObjectOutputStream gebruikt natuurlijk, maar als je met een gewone (Buffered)OutputStream ofzo werkt moet je wel even opletten dat het aantal bytes dat je verstuurd niet perse in één batch aankomt...
(dus 1000 bytes tegelijk versturen betekend niet dat je ook 1000 bytes tegelijk ontvangt...)

Verwijderd

Topicstarter
Dus een inputstreamreader zorg er niet voor dat de string in 1 keer aankomt
ik moet dus een objectoutputstream gebruiken?

en hoe zit het dan met die sockets, moet ik die in een array plaatsen?

Verwijderd

ACM schreef op 29 september 2002 @ 17:02:
[...]

Dat is niet helemaal waar :)
Wel als je de ObjectOutputStream gebruikt natuurlijk, maar als je met een gewone (Buffered)OutputStream ofzo werkt moet je wel even opletten dat het aantal bytes dat je verstuurd niet perse in één batch aankomt...
(dus 1000 bytes tegelijk versturen betekend niet dat je ook 1000 bytes tegelijk ontvangt...)
Maar merk je dat in de praktijk ook, of is dit meer een technisch-detail-dat-leuk-is-om-te-weten iets? :)

edit:
En dan heb ik het over het geval dat er aan de andere kant van de lijn ook een java client zit

Verwijderd

Topicstarter
zoals zef stelt idd
als ik controleer of de line.equals(bepaalde waarde), kaner dan een probleem optreden?

Verwijderd

Hoi,

Wat is precies de bedoeling van je projectje? Een chat systeem maken ofzo?

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Verwijderd schreef op 29 september 2002 @ 17:10:
Dus een inputstreamreader zorg er niet voor dat de string in 1 keer aankomt
ik moet dus een objectoutputstream gebruiken?

en hoe zit het dan met die sockets, moet ik die in een array plaatsen?

Niks moet :)
Je kan prima een inputstreamreader gebruiken om een string in te lezen, maar let er dan wel op dat je even aan de socket vraagt of er nog data te lezen is.

ObjectIn/OutputStream is trouwens sowieso erg makkelijk met Strings enzo, dus wat dat betreft is dat een aanrader :)
Verwijderd schreef op 29 september 2002 @ 17:11:
Maar merk je dat in de praktijk ook, of is dit meer een technisch-detail-dat-leuk-is-om-te-weten iets? :)

edit:
En dan heb ik het over het geval dat er aan de andere kant van de lijn ook een java client zit
Ja, daar kan je in de praktijk heel wel last van hebben :)
Ik had een bug precies andersom gemaakt, ik ging er vanuit dat als ik 1000 bytes stuurde in een batch er ook 1000 bytes aankwamen, maar er kwamen er bijv maar 345 aan (die andere kwamen later pas, tcp-gedoe enzo he? :) ).
Vervolgens schreef ik WEL 1000 bytes (ik had tenslotte een buffer van 1000 bytes en die schreef ik gewoon allemaal weg) weg naar een file...
Toen waren ineens alle files corrupt :+

Oplossing was natuurlijk simpel, kijk hoeveel bytes er gelezen zijn en schrijf ook zoveel bytes weg...
Verwijderd schreef op 29 september 2002 @ 17:15:
zoals zef stelt idd
als ik controleer of de line.equals(bepaalde waarde), kaner dan een probleem optreden?
Hangt er dus helemaal van af wat je wilt.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
ACM: Ja, daar kan je in de praktijk heel wel last van hebben :)
Misschien ben ik de enige, maar volgens mij ontstaat er nu toch een klein beetje een verkeerd beeld. Als je niet goed leest of niet goed begrijpt wat je schrijft (je zegt het dus wel allemaal goed ;) ), zou je namelijk kunnen denken dat die bytes een beetje door elkaar gehutseld of niet volledig verzonden worden ivm allerlei transport moeilijkheden. Dat zou natuurlijk behoorlijk onwenselijk zijn.

Wat er aan de hand was in dit geval: ACM controleerde niet of de array die hij gebruiktte als buffer ook daadwerkelijk volledig gevuld werd. Als je bytes inleest in zo'n buffer, krijg je altijd een int terug: het aantal gelezen bytes. Daar moet je dus wel even goed naar kijken en je moet er nooit vanuit gegaan dat je volledige byte array gevuld is met data die via de socket binnen is gekomen (dit geldt overigens voor alle InputStreams, niet alleen voor die van sockets).

TCP zorgt er dus wel voor dat alle bytes verzonden worden en dat ze in de goede volgorde verzonden worden. TCP is niet voor niets ontworpen als een betrouwbaar protocol voor onbetrouwbare verbindingen. Eigen checks (zoals bijvoorbeeld het meezenden van het aantal bytes of een bepaalde statistiek over de gegevens) zijn dus in principe niet nodig en dus overbodig. Wel moet je even goed kijken hoe je bytes moet inlezen :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Damn, mbravenboer weet dat weer veel beter uit te leggen dan ik :P

Maar idd, de bytes kwamen allemaal aan en ook allemaal op de goede volgorde, alleen niet allemaal in even grote brokken en ook niet in de brokken die ik verzond.
Terwijl ik ze wel verzond in even grote brokken (althans... dat kan natuurlijk over het algemeen helemaal niet met ethernet+tcp om packets van 1000 bytes te sturen, magoed :) )

Nadeel is wel, als je meerdere strings achter elkaar wilt sturen je niet met enorme zekerheid kan zeggen waar de ene begint en de ander eindigt.
Tenzij je bijv een delimiter ertussen propt (\n ofzo) die in je strings nooit voor mag komen.

Vandaar de Object-streams als tip, deze zorgen er gewoon voor dat het hele object binnenkomt en zorgen ervoor dat je niet van die foutjes kan maken als ik deed :)

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
ACM: Damn, mbravenboer weet dat weer veel beter uit te leggen dan ik :P
Sorry ;) .
Nadeel is wel, als je meerdere strings achter elkaar wilt sturen je niet met enorme zekerheid kan zeggen waar de ene begint en de ander eindigt. Tenzij je bijv een delimiter ertussen propt (\n ofzo) die in je strings nooit voor mag komen.
Idd, je moet dus nooit zo maar uitgaan van de brokken waarin jij de info de lijn opstuurt. Sockets leveren gewoon een stream van bytes via de InputStreams en het is niet de bedoeling (en dus fout ;) ) dat je daarbij gebruik gaat maken van bepaalde aannamen over de manier waarop die bytes verzonden worden. Als je dus iets in pakketten wilt versturen, zal je zelf een scheiding moeten aanbrengen.
Vandaar de Object-streams als tip, deze zorgen er gewoon voor dat het hele object binnenkomt en zorgen ervoor dat je niet van die foutjes kan maken als ik deed :)
Hum tja... Ik ben zelf niet zo'n fan van objectstreams, maar het kan inderdaad wel makkelijk werken. Ik zou het persoonlijk dan liever in de vorm van XML versturen, maar ja ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

Je kan natuurlijk ook een BufferedReader aan een Inputstream koppelen en met de methode getLine() de strings er als regels uitlezen. De andere kant op doe je dan met een Printwriter en de OutputStream van de socket. Op die manier kun je gewoon met \n afgesloten Strings zonder problemen oversturen (wel de println() methode van de PrintWriter gebruiken)

Verwijderd

mbravenboer schreef op 29 september 2002 @ 18:03:
Wat er aan de hand was in dit geval: ACM controleerde niet of de array die hij gebruiktte als buffer ook daadwerkelijk volledig gevuld werd. Als je bytes inleest in zo'n buffer, krijg je altijd een int terug: het aantal gelezen bytes. Daar moet je dus wel even goed naar kijken en je moet er nooit vanuit gegaan dat je volledige byte array gevuld is met data die via de socket binnen is gekomen (dit geldt overigens voor alle InputStreams, niet alleen voor die van sockets).
Ja, ik was bijna in precies hetzelfde getuimt onlangs. Maar dankzij een geweldige redding van mbravenboer kwam dat toch allemaal weer goed :+ Hier was dat meen ik: [rml][ Java Servlet] GIF sturen[/rml]

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
wasigh: Printwriter
Ik ben zelf absoluut geen fan van PrintWriter: deze is met name bedoeld voor IO zonder last te hebben van Exceptions. Het is dus niet zo verstandig om voor PrintWriter te kiezen omdat deze wat handige methode heeft zoals println. Als je kiest voor de PrintWriter, kies je voor IO zonder exceptions.

BufferedWriter kent ook een newLine methode. Als je heel graag een writeln wilt, kan je zelf even een Writer schrijven die alles forward naar een andere writer en bovendien een methode writeln heeft. Dit is een soort toepassing van het Decorator pattern zoals je dat ook ziet toegepast bij de BufferedWriter.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

Topicstarter
ok dan,
ik denk dat ik het via ObjectStreams ga doen,
lijkt me veiliger
maar nu vraag ik me dan wel 1 ding af, hoe kan ik dan weten of er een object aan het binnenstromen is op de server of op de client
is daar een listener voor?

en ja
de bedoeling is om heel sumier een chat systeem te bouwen, just for fun

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Ja natuurlijk is dat er :)

Een socket heeft een inputstream en een outputstream, om beide kan je een objectinput/outputstream plakken en er een thread (ofzo) aan hangen die gaat lopen luisteren in je client.

Verwijderd

Topicstarter
dus, even voor de duidelijkheid,
want morgen begin ik eraan

ik laat in een thread constant proberen, dmv try{} een object uit de stream te parsen?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 31-08 15:26

.oisyn

Moderator Devschuur®

Demotivational Speaker

je kunt natuurlijk ook met de (read|write)UTF functies van Data(Input|Output)Stream werken

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Bedenk ook dat het gebruik van de Object*Streams het vrijwel onmogelijk maakt om vanuit een andere taal/platform te communiceren met de client of server die in Java geschreven is. Het 'protocol' wat wordt gebruikt is zeer Java specifiek en daardoor vrijwel niet na te bootsen in andere talen/platformen.

Als je gebruik maakt van 'primitievere' middelen zoals scheidingstekens, XML of wat dan ook en goed nadenkt over je protocol, dan is het goed mogelijk om componenten in andere talen te schrijven.

Op zich maakt het voor een speel project niet zoveel uit, maar het is misschien toch goed om te weten :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 31-08 15:26

.oisyn

Moderator Devschuur®

Demotivational Speaker

mbravenboer schreef op 30 september 2002 @ 03:31:
Bedenk ook dat het gebruik van de Object*Streams het vrijwel onmogelijk maakt om vanuit een andere taal/platform te communiceren met de client of server die in Java geschreven is. Het 'protocol' wat wordt gebruikt is zeer Java specifiek en daardoor vrijwel niet na te bootsen in andere talen/platformen.

Als je gebruik maakt van 'primitievere' middelen zoals scheidingstekens, XML of wat dan ook en goed nadenkt over je protocol, dan is het goed mogelijk om componenten in andere talen te schrijven.

Op zich maakt het voor een speel project niet zoveel uit, maar het is misschien toch goed om te weten :) .
.oisyn schreef op 30 september 2002 @ 03:27:
je kunt natuurlijk ook met de (read|write)UTF functies van Data(Input|Output)Stream werken
:+ ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
.oisyn: :+ ;)
Het waarom en het hoe en dat midden in de nacht! :+ .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

dus, even voor de duidelijkheid,
want morgen begin ik eraan

ik laat in een thread constant proberen, dmv try{} een object uit de stream te parsen?
ff voor de duidelijkheid: de thread is niet constant bezig met checken. De inputstream blokkeert de thread zolang hij niks te doen heeft. Hierdoor 'hangt' je lees-thread (dit is ook de reden _waarom_ je een extra thread nodig hebt).

Verwijderd

Topicstarter
de inputstream blokeert die?
hoe dan, als ik dat in een lusje laat checken blokeert die stream dat toch niet?

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Ik neem aan dat er bij het ophalen van data een down wordt gedaan op een semafoor. En als er dan niets te halen is, zal de aanroepende thread slapen totdat er weer data beschikbaar is.

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 30-08 17:59

Gerco

Professional Newbie

De call naar readObject() blokkeert zolang er niets (of een onvolledig object) te lezen is, dus je lees-thread hangt. Je loop loopt dus ook maar 1x per object en niet constant waarbij er af-en-toe een object gelezen wordt. Iedere iteratie van de lus heb je een object (kan ook null zijn als er een exception oid optreed).

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Verwijderd

Topicstarter
concreet

een nieuwe thread aanmaken
en dan in de
public void run()
{
dip.readObject()
}
?

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op die manier zou je inderdaad die stream kunnen checken op binnenwandelende objecten. Je moet dan natuurlijk wel een signaal (misschien mbv een event) moeten afgeven om te laten zien dat er een object is binnen gekomen. Pas hierbij wel enorm op dat je geen concurrency problemen gaat krijgen.

[edit]
jouw thead die kan maar 1 object binnen halen, je zal het dus wel even in een lusje moeten plaatsen.

public void run(){
...while(true){
......dip.readObject();
......//geef signaal door dat er iets is binnen gekomen.
...}
}

Verwijderd

Topicstarter
dit sginaal dacht ik dan te doen door in die lus
public void run(){
...while(true){
......dip.readObject();
......
try
{
parse object
}
catch (Exception e)
{}
//geef signaal door dat er iets is binnen gekomen.
...}
}

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

De code die ik hier voor me zie is niet correct of er is iets misgegaan.

Verwijderd

Topicstarter
ok
kheb de oplossing van dit zaakje gevonden
ik kan inloggen od server
en de server kan me iets toesturen

we gaan dus verder ;)

Verwijderd

Topicstarter
hallo,
even nog een vraagje hierrond
het is gelukt om een simpel chatprogrammaatje te maken
nu vroeg ik mij af
zijn er ook sockets die veiliger werken (maw encrypted) of zoiets?
Pagina: 1