[C#] TcpClient verstuurt data te snel (strings aan elkaar) *

Pagina: 1
Acties:
  • 540 views sinds 30-01-2008
  • Reageer

  • ThaStealth
  • Registratie: Oktober 2004
  • Laatst online: 27-11 13:59
Hoi,

Voor project maak ik gebruik van TcpClient en TcpServer, de client verstuurd een lap met strings richting de server middels de volgende code:

C#:
1
2
3
4
5
6
7
8
9
10
        public void SchrijfServer(string data)
        {
            if (Tcpclient.Client.Connected)
            {
                Byte[] bBuf;
                bBuf = ASCII.GetBytes(data);
                Tcpclient.Client.Send(
                Tcpclient.Client.Send(bBuf, 0, bBuf.Length, 0);                
            }
        }


het probleem is nu dat als ik het bijvoorbeeld het volgende bericht verstuur:
bla
bli
blo
maar ik het volgende binnen krijg: blabliblo, dit is niet helemaal mijn bedoeling, aangezien ik dit gesplitst wil hebben.

Is het misschien mogelijk om elk woord op een aparte regel te krijgen (en eventueel op te vullen met \0 tekens?

Mess with the best, die like the rest


  • Kuhlie
  • Registratie: December 2002
  • Niet online
ThaStealth schreef op vrijdag 29 juni 2007 @ 12:07:
Is het misschien mogelijk om elk woord op een aparte regel te krijgen (en eventueel op te vullen met \0 tekens?
Heb je dit al geprobeerd? Wat ging er mis?

Edit: misschien flauw, maar het lijkt dat je een probleem tegen kwam, het probleem beschreven hebt, en dat probleem hier hebt gepost. Hier ziet men graag wat je geprobeerd hebt om het op te lossen, en waarom dat niet werkte.

[ Voor 29% gewijzigd door Kuhlie op 29-06-2007 12:16 ]


  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 27-11 13:24
ThaStealth schreef op vrijdag 29 juni 2007 @ 12:07:
Is het misschien mogelijk om elk woord op een aparte regel te krijgen (en eventueel op te vullen met \0 tekens?
TCP is een continue stream van bytes, dus er is helemaal geen sprake van dat een enkele "send" ook overeenkomt met wat je in een "recv" terugkrijgt. Het is ook heel goed mogelijk dat je bijvoorbeeld per recv maar 1 byte per keer terugkrijgt!

Je zult dus zelf moeten zorgen voor:
- afbakening van je eigen messages door tokens, messages van vaste lengte of door eerst de lengte door te sturen
- buffering van nog niet complete messages, totdat ie volledig ontvangen is
- enige vorm van robuustheid/security/foutafhandeling hierin

  • SjonnieX
  • Registratie: Juni 2007
  • Laatst online: 15-04 21:57
en vergeet niet \r\n (carriage-return, linefeed) aan je string toe te voegen als iedere string op een nieuwe regel gezet moet worden.

  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 01:48

Reptile209

- gers -

SjonnieX schreef op vrijdag 29 juni 2007 @ 21:44:
en vergeet niet \r\n (carriage-return, linefeed) aan je string toe te voegen als iedere string op een nieuwe regel gezet moet worden.
Da's natuurlijk leuk cosmetisch als je de ontvangen data bijvoorbeeld naar een textbox gooit. Voor de functionaliteit maakt het geen klap uit of je nou een \r\n, een #, een 1 of je naam als scheidingsteken(s) gebruikt. Je hebt gewoon een goede buffer nodig die op basis van je scheidingsteken(s) strings in stukjes knipt en doorgeeft aan de rest van je programma. Je programma kan cosmetische zaken als regelterugloop afhandelen.

[ Voor 5% gewijzigd door Reptile209 op 29-06-2007 22:06 ]

Zo scherp als een voetbal!


  • CodeIT
  • Registratie: Juni 2002
  • Laatst online: 21:22

CodeIT

Code IT

Ik maak meestal zelf een "headertje" wat aangeeft hoeveel bytes er verstuurd zijn. Dit is dan bij de client makkelijk te bufferen. Nadeel hiervan is dat je wel zelf iets met time-outs moet regelen.
Als de strings die je gaat versturen toch geen newline bevatten, kun je overal een new-line achter zetten.

  • Swerfer
  • Registratie: Mei 2003
  • Laatst online: 30-11 10:16

Swerfer

Hmm...

Je kan als token bijvoorbeeld een komma gebruiken, en als het complete bericht binnen is gehaald in een string, dan kan je het Split commando gebruiken...

[ Voor 6% gewijzigd door Swerfer op 01-07-2007 10:16 ]

Home Assistant | Unifi | LG 51MR.U44 | Volvo EX30 SMER+ Vapour Grey, trekhaak | SmartEVSE V3 | Cronos Crypto.com


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 20:19

Gerco

Professional Newbie

In plaats van zelf het wiel (opnieuw) uit te vinden, kun je ook iets als Bencoding gebruiken. Zeer weinig overhead (meestal maar 1 of 2 tekens bovenop wat je zelf zou bedenken), maar wel flexibel. Dan hoef je niet voor iedere release van je programma je compatibiliteit te verbreken :)
While less efficient than a pure binary encoding, bencoding is simple and (because numbers are encoded in decimal notation) is unaffected by endianness, which is important for a cross platform application like BitTorrent. It is also fairly flexible, as long as applications ignore unexpected dictionary keys, so that new ones can be added without creating incompatibilities.

[ Voor 36% gewijzigd door Gerco op 01-07-2007 10:43 ]

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


  • ThaStealth
  • Registratie: Oktober 2004
  • Laatst online: 27-11 13:59
Had zelf al een id met opvullen met spaties en die op de ontvangstzijde weg te trimmen, maar dat zorgde ervoor dat ie ehm, 100x zo traag werd (regels zijn maximaal 20-30 karakters, dus dat werden heleboel whitespaces)

dat bencoding ga ik nu es uitvogeln

Mess with the best, die like the rest


  • GENETX
  • Registratie: Juni 2005
  • Laatst online: 22:43
Zelf hadden wij op school een project waar we gebruik van TCP/IP moesten maken. Ik programmeer dan wel in delphi, maar wie weet heb je wat aan het idee.

Ik heb het als volgt aangepakt om een standaard layout voor alle commando's en data op te stellen in een stringlist.

Zo kreeg ik:

code:
1
2
3
4
IP-adres
commando
data
end


Met commando login bijvoorbeeld

code:
1
2
3
4
5
IP-adres
login
gebruikersnaam
wachtwoord
end


Dit werkte perfect en zolang de stringlist niet te lang werd (dus niet 500 meetgegevens er in 1 keer doorheen jassen ;) ) werkt dit prima. Op de server kon ik mooi makkelijk per regel alles bekijken en het vergde hier dus geen lastige code. Kwam er zelf met toeval achter toen ik de inhoud van een memo in een keer te versturen wat tot mn verbazing goed ging.

  • Kuhlie
  • Registratie: December 2002
  • Niet online
In java heb je overigens (naar mijn mening) nette ObjectStreams:
Java:
1
2
3
4
5
ObjectInputStream inputstream = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream outputstream = new ObjectOutputStream(socket.getOutputStream());
String password = (String)(inputstream.readObject());
String message = "een string";
outputstream.writeObject(message);
waar je alle objecten die serializable zijn overheen kunt gooien.

Is er niet ook zoiets in C#?

  • ThaStealth
  • Registratie: Oktober 2004
  • Laatst online: 27-11 13:59
Jawel dat bestaat ook in C#, alleen gebruik ik het compact framework (communicatie van PDA naar PC) en ben niet helemaal zeker hoe dat daarin werkt

Mess with the best, die like the rest


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

CodeIT schreef op zaterdag 30 juni 2007 @ 17:34:
Ik maak meestal zelf een "headertje" wat aangeeft hoeveel bytes er verstuurd zijn. Dit is dan bij de client makkelijk te bufferen. Nadeel hiervan is dat je wel zelf iets met time-outs moet regelen.
Timeouts? Je moet gewoon niet meteen een botte read doen van x bytes, maar gewoon kijken hoeveel er in de buffer staat, en het bericht pas helemaal afhandelen als je er genoeg hebt.

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.


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
.oisyn schreef op zondag 01 juli 2007 @ 14:45:
Timeouts? Je moet gewoon niet meteen een botte read doen van x bytes, maar gewoon kijken hoeveel er in de buffer staat, en het bericht pas helemaal afhandelen als je er genoeg hebt.
Als je geen scheidingsteken wilt/kunt gebruiken zul je iets anders moeten gebruiken. Normaal gesproken gebruik je dan interbyte tijd als scheidingscriteria. Dit vertaalt zich bij het inlezen ervan tot het gebruik van een timout op de read.

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.


  • CodeIT
  • Registratie: Juni 2002
  • Laatst online: 21:22

CodeIT

Code IT

.oisyn schreef op zondag 01 juli 2007 @ 14:45:
[...]

Timeouts? Je moet gewoon niet meteen een botte read doen van x bytes, maar gewoon kijken hoeveel er in de buffer staat, en het bericht pas helemaal afhandelen als je er genoeg hebt.
Dat lijkt me logisch. Ik bedoelde de timeouts die ik gebruik voor clients die niet helemaal binnen de specs van het protocol de data versturen (bijv. te weining) en dit dan af te vangen zodat je niet constant op de resterende bytes staat te wachten die niet meer komen.
Pagina: 1