Toon posts:

[java] socket - c++ client

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb een server-cliënt applicatie die bestaat uit een java-server en een c++-cliënt.
Er kunnen meerdere cliënts een socket verbinding opbouwen met deze java-server-applicatie.
Deze verbindingen blijven openstaan zolang de cliënt opgestart blijft.

Probleem is dat wanneer er een grote hoeveelheid data (XML) va de server naar de cliënt wordt gestuurd het CPU-gebruik op de cliënt soms bijna 1 minuut op 100% staat.

Nu ben ik er na veel zoeken achter dat dit komt omdat de server heel veel kleine pakketjes naar de cliënt stuurt en deze dus telkens apart door de client worden afgewerkt. Per pakketje worden slecht enkele karakters verwerkt.
Ik heb het vermoeden dat het iets met buffer-instellingen te maken heeft, alleen kom er zelf niet uit. Ook met veel googlen kom ik er niet uit.

  • moto-moi
  • Registratie: Juli 2001
  • Laatst online: 09-06-2011

moto-moi

Ja, ik haat jou ook :w

Je kunt je vast wel voorstellen dat dit probleem een stuk duidelijker wordt met wat snipets denk ik? ;)

God, root, what is difference? | Talga Vassternich | IBM zuigt


  • martennis
  • Registratie: Juli 2005
  • Laatst online: 16-01 14:17
kun je eens een stuk code plaatsen met het gedeelte dat de XML verstuurd?

Verwijderd

Topicstarter
martennis schreef op vrijdag 25 augustus 2006 @ 16:24:
kun je eens een stuk code plaatsen met het gedeelte dat de XML verstuurd?
1) outputStream = new DataOutputStream(socket.getOutputStream());
2) outputStream.writeBytes(s);

Deze regel 2 verstuurd in één keer een grote lap XML, als ik een println doe op de server wordt deze ook in één actie weg geschreven, echter de cliënt krijgt deze denk ik per byte binnen, of in iedergeval in heel kleine stukjes


De çliënt is gebouwd in Borland c++ 6. Daar gebruik ik TClientSocket component en het event "OnRead"
Vervolgens maakt deze regel 3 de cliënt traag:
3) Socket->ReceiveText();
Als ik op de cliënt een check doe blijkt ook dat deze regel 3 heel baak wordt aangeroepen

[ Voor 21% gewijzigd door Verwijderd op 25-08-2006 16:45 ]


  • MetroidPrime
  • Registratie: Oktober 2003
  • Laatst online: 25-01 09:16

MetroidPrime

Turn it up loud, captain!

Probeer tussen de socket OutputStream en de DataOutputStream eens een BufferedOutputStream te gebruiken. Dan krijg je zoiets:
Java:
1
2
outputStream = new new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
outputStream.writeBytes(s);


De output zal dan in een buffer worden opgeslagen en pas als de buffer vol zit zal de data verzonden worden.

[ Voor 17% gewijzigd door MetroidPrime op 25-08-2006 16:45 ]

"Some girl on the street outside the bar just asked me if I was saved yet." "Yeah? What did you say?" "I told her 'I saved at the checkpoint a couple of minutes back and I can reload from there if I die.'


Verwijderd

Topicstarter
MetroidPrime schreef op vrijdag 25 augustus 2006 @ 16:43:
Probeer tussen de socket OutputStream en de DataOutputStream eens een BufferedOutputStream te gebruiken. Dan krijg je zoiets:
Java:
1
2
outputStream = new new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
outputStream.writeBytes(s);


De output zal dan in een buffer worden opgeslagen en pas als de buffer vol zit zal de data verzonden worden.
Dit gaat al een stuk beter.
Het probleem van kleine datapakketjes is opgelost, maar nu wordt alleen de XML-message halverwege afgebroken. Dus ik krijg de complete message niet meer over.
Kan het zijn dat de BufferedOutputStream een maximale hoeveelheid data aan kan ?

  • MetroidPrime
  • Registratie: Oktober 2003
  • Laatst online: 25-01 09:16

MetroidPrime

Turn it up loud, captain!

Verwijderd schreef op vrijdag 25 augustus 2006 @ 16:59:
[...]


Dit gaat al een stuk beter.
Het probleem van kleine datapakketjes is opgelost, maar nu wordt alleen de XML-message halverwege afgebroken. Dus ik krijg de complete message niet meer over.
Kan het zijn dat de BufferedOutputStream een maximale hoeveelheid data aan kan ?
Er is geen maximum hoeveelheid data voor een BufferedOuputStream, voor zover ik weet. Ik heb BufferedOutputStream zelf vaak genoeg gebruikt met bestanden van enkele tientallen gigabytes.

[ Voor 26% gewijzigd door MetroidPrime op 25-08-2006 17:17 ]

"Some girl on the street outside the bar just asked me if I was saved yet." "Yeah? What did you say?" "I told her 'I saved at the checkpoint a couple of minutes back and I can reload from there if I die.'


  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 14-02 11:33
Verwijderd schreef op vrijdag 25 augustus 2006 @ 16:59:
[...]


Dit gaat al een stuk beter.
Het probleem van kleine datapakketjes is opgelost, maar nu wordt alleen de XML-message halverwege afgebroken. Dus ik krijg de complete message niet meer over.
Kan het zijn dat de BufferedOutputStream een maximale hoeveelheid data aan kan ?
Je moet wel flush() aanroepen wanneer je alles naar de BufferedOutputStream hebt geschreven.

Je kan ook eens kijken of TCP_NODELAY (Nagle) toevallig aan staat. Als het goed is staat dit standaard uit.

  • martennis
  • Registratie: Juli 2005
  • Laatst online: 16-01 14:17
is de buffer op de server-side misschien te klein?
of misschien krijgt de socket een time-out?

houd ons even op de hoogte :)

  • MetroidPrime
  • Registratie: Oktober 2003
  • Laatst online: 25-01 09:16

MetroidPrime

Turn it up loud, captain!

matthijsln schreef op vrijdag 25 augustus 2006 @ 17:29:
[...]


Je moet wel flush() aanroepen wanneer je alles naar de BufferedOutputStream hebt geschreven.

Je kan ook eens kijken of TCP_NODELAY (Nagle) toevallig aan staat. Als het goed is staat dit standaard uit.
Inderdaad een flush() of een close() is als je klaar bent bij BufferedOutputStream noodzakelijk omdat er anders bytes in de buffer blijven steken.
martennis schreef op vrijdag 25 augustus 2006 @ 17:49:
is de buffer op de server-side misschien te klein?
Dat zou geen probleem mogen zijn omdat de buffer van een BufferedOutputStream automatisch geflushed wordt als deze vol zit.

"Some girl on the street outside the bar just asked me if I was saved yet." "Yeah? What did you say?" "I told her 'I saved at the checkpoint a couple of minutes back and I can reload from there if I die.'


Verwijderd

Topicstarter
matthijsln schreef op vrijdag 25 augustus 2006 @ 17:29:
[...]


Je moet wel flush() aanroepen wanneer je alles naar de BufferedOutputStream hebt geschreven.

Je kan ook eens kijken of TCP_NODELAY (Nagle) toevallig aan staat. Als het goed is staat dit standaard uit.
Het was nog eventjes problematisch waarom het mij neit wordt lukken, maar 'k maakte de fout door eerst de flushen en daarna de write te gebruiken.

Dus probleem is nu opgelost, gebruik deze stappen:
1) outputStream = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
2) outputStream.writeBytes(s);
3) outputStream.flush();

bedank voor alle hulp

  • MetroidPrime
  • Registratie: Oktober 2003
  • Laatst online: 25-01 09:16

MetroidPrime

Turn it up loud, captain!

Ik moet er wel even bij vermelden dat er zodra je klaar bent en een flush() doet, het wel netjes is om daarna een close() te doen. Als je een close() doet worden alle resources die aan de OutputStream verbonden zijn vrijgegeven.

"Some girl on the street outside the bar just asked me if I was saved yet." "Yeah? What did you say?" "I told her 'I saved at the checkpoint a couple of minutes back and I can reload from there if I die.'


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 23:54
Beste mensen, als je dit soort instellingen moet wijzigen om een paar bytes heen en weer te ktijgen ben je verkeerd bezig.

Ik denk dat je je client code nog eens zeer critisch moet bekijken. 100% CPU betekent dat je je threads uitdroogt. Ook al gebruik je nu een buffered stream, je hebt geen enkele garantie dat deze stream ook in 1 keer aan de andere kant aankomt.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • The Fox NL
  • Registratie: Oktober 2004
  • Laatst online: 22:37
MetroidPrime schreef op vrijdag 25 augustus 2006 @ 18:21:
Ik moet er wel even bij vermelden dat er zodra je klaar bent en een flush() doet, het wel netjes is om daarna een close() te doen. Als je een close() doet worden alle resources die aan de OutputStream verbonden zijn vrijgegeven.
Als ik de OP zo lees is het de bedoeling dat de verbinding open blijft totdat de client de verbinding afkapt. Ik zou de OutputStream dus gewoon openlaten. Maar als de OutputStream niet meer gebruikt gaat worden is het inderdaad netjes om close() te doen.

  • MetroidPrime
  • Registratie: Oktober 2003
  • Laatst online: 25-01 09:16

MetroidPrime

Turn it up loud, captain!

The Fox NL schreef op vrijdag 25 augustus 2006 @ 21:42:
[...]


Als ik de OP zo lees is het de bedoeling dat de verbinding open blijft totdat de client de verbinding afkapt. Ik zou de OutputStream dus gewoon openlaten. Maar als de OutputStream niet meer gebruikt gaat worden is het inderdaad netjes om close() te doen.
Oeps, daar had ik overheen gelezen.

"Some girl on the street outside the bar just asked me if I was saved yet." "Yeah? What did you say?" "I told her 'I saved at the checkpoint a couple of minutes back and I can reload from there if I die.'

Pagina: 1