Toon posts:

[VB] Winsock getdata -> data achter elkaar?

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben met een chat-programma bezig, het heeft een server en een client.
op het moment dat een client van de server disconnect (dus de connection_close-event op de server) dan stuurt de server eerst naar alle clients:
"QIT User bla bla has quit"
en daarna stuurt de server een update van alle aanwezige clients in de vorm van:
"UPD id:username:status id2:username2:status"
het probleem is nu dat op de client dit binnenkomt als
"QIT User bla bla has quitUPD id:username:status id2:username2:status"
terwijl het wel apart verzonden word door de server. ik heb hier tot nu toe met andere commands nog geen last mee gehad, maar als dit komt doordat de server data die snel achter elkaar word verzonden achter elkaar plakt, dan kan het nog een probleem worden op het moment dat meerdere users snel achter elkaar messages sturen.

wat is hier het probleem? (en hoe los ik het op?)

[ Voor 3% gewijzigd door Verwijderd op 19-11-2003 21:50 ]


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

TCP let niet op message boundaries, het maakt niet uit of het in stukjes verzonden wordt of als geheel, er is geen enkele garantie dat het in diezelfde verdeling aankomt. Je moet het zien als een stroom van data in beide richtingen.
Oplossing is zelf message delimiters te maken, dat kan op allerlei manieren. Bijvoorbeeld elk bericht afsluiten met een enter (als het tekst is). Vervolgens de stroom data parsen zodat je de berichtjes er weer uit kan halen (rekening houdend met het feit dat er dus stukjes bericht of juist meer dan 1 bericht in de buffer kunnen zitten).

www.madwizard.org


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 00:47
't is iets van dit
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
Private Sub Socket_OnDataArrival()

    'Lees de volledige string die ontvangen is, plak die aan de bewaarde string
    Static data As String
    data = data & Socket.GetData

    'Kijk of er een volledig bericht in de string zit, handel em evt af

    'Bewaar de rest van de string voor de volgende dataarrival

End Sub

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.


  • Sponge
  • Registratie: Januari 2002
  • Laatst online: 15-08 11:47

Sponge

Serious Game Developer

Hmm, volgens mij werkte dit gewoon:

Winsock.senddata string & vbCrLf
{doevents} '//optioneel dus.

Verder is TCP dus inderdaad stream based, en kan dit gewoon voorkomen. Je kan ook UDP gaan gebruiken, maar dan moet je je eigen systeem bouwen om berichten in de juiste volgorde ontvangen, en als een bericht "verdwijnt", het opnieuw versturen (UDP packets worden namelijk niet opnieuw verzonden bij packetloss)

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 00:47
Sponge schreef op 20 november 2003 @ 08:27:
Hmm, volgens mij werkte dit gewoon:

Winsock.senddata string & vbCrLf
{doevents} '//optioneel dus.
Dat zal zeker niet de garantie geven dat de data ook verstuurd wordt, en bovendien raad ik het gebruikt van DoEvents sterk af. ( Alleen als je niet anders kunt )

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.


Verwijderd

Topicstarter
en zoiets: ?

Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 Private Sub sckChat_DataArrival(ByVal bytesTotal As Long)
  Dim Data as String
  Dim i as Integer
  Dim arrdata as String

  sckChat.getdata Data

  arrData = Split(Data,vbCrLf)

  for i = 0 To UBound(arrData)
   'parse de string die in arrData(i) zit
  next i
  
 End Sub


ik heb dit net ff snel geprobeerd, maar volgensmij heb ik ergens een variabele niet goed gedeclareerd want ik krijg vreemde data :/

[ Voor 6% gewijzigd door Verwijderd op 20-11-2003 13:49 ]


Verwijderd

Topicstarter
probleem opgelost :)
ik had een variabele verkeerd gedeclareerd. ik heb vbCrlf als scheiding van commands gedaan en alle uitgaande messages vbcrlf vervangen door vblf (om toch messages met meerdere regels te kunnen doen)

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 16-08 21:36
farlane schreef op 20 november 2003 @ 00:12:
't is iets van dit
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
Private Sub Socket_OnDataArrival()

    'Lees de volledige string die ontvangen is, plak die aan de bewaarde string
    Static data As String
    data = data & Socket.GetData

    'Kijk of er een volledig bericht in de string zit, handel em evt af

    'Bewaar de rest van de string voor de volgende dataarrival

End Sub
En als je nou twee sockets hebt, hoe hou je dan de data van de een gescheiden van de data van de ander?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • DukeMan
  • Registratie: Mei 2000
  • Niet online
Als je eerste socket Socket1 heet en de tweede socket2, zijn die static alleen beschikbaar in desbetreffende OnDataArrivel subs. Wanneer je een array hebt van die sockets (dus socket(0) en socket(1)) kan je het beste "data" ook als array declareren en dan de index van de socket gebruiken als index in data

Ala:

Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
Private Sub Socket_OnDataArrival(Index as Integer)

    'Lees de volledige string die ontvangen is, plak die aan de bewaarde string
    Static data() As String
    data(index) = data(Index) & Socket.GetData

    'Kijk of er een volledig bericht in de string zit, handel em evt af

    'Bewaar de rest van de string voor de volgende dataarrival

End Sub


Zorg er wel voor dat je Data(index) dimt... misschien dat je er beter een public variabele van kan maken en die in een module zetten, dan kan je data redimmen bij het opstarten van je app of bij het maken/sluiten van een connectie...
Pagina: 1