|
| Winsok, Array Fra : Thor Olsen |
Dato : 27-12-02 19:12 |
|
Har lavet et lille Server - Client chat program i VB60 programmet virker
fint når jeg vil sende tekst. Men når jeg vil sende og modtage et "array of
byte" går det fløjten jeg læser kun værdien 0 i alle mine array i "MsgBox"
på Client siden. Er der nogen der ved hvorledes jeg Sender/Modtager et
Array of byte. Her er et udsnit af min kode
Server.:
Private Sub Command1_Click()
Dim ByteArray(2) As Byte
ByteArray(0) = 99
ByteArray(1) = 99
If Text2.Text <> "" Then
Wsck.SendData "PAKKE2"
Wsck.SendData (ByteArray)
Else
MsgBox "No Client Present" 'Client ikke til stede hvis
Text2.Text er tom
End If
End Sub
Client.:
Private Sub Wsck_DataArrival(ByVal bytesTotal As Long)
Dim UdData As String
Dim UdArray(4) As Byte
Wsck.GetData UdData, vbString 'Modtag data fra server og læg det
i variablen UdData
If UdData = "PAKKE1" Then '"DETTE VIRKER FINT NÅR JEG MODTAGER
TEKST"
Wsck.GetData UdData, vbString 'Modtag data fra server og læg
det i variablen UdData
List1.AddItem UdData
List1.AddItem ("")
ElseIf UdData = "PAKKE2" Then '"NÅR JEG SKAL MODTAGE ET ARRAY FÅR
JEG KUN VÆRDIEN 0 i MIN MsgBox"
Wsck.GetData UdArray, vbArray + vbByte
MsgBox (UdArray(0) & Chr$(13) & UdArray(1))' værdier virker ikke
der bliver skrevet 0 i samtlige UdArray
Else
MsgBox "Fejl"
End If
End Sub
| |
Tomas Christiansen (27-12-2002)
| Kommentar Fra : Tomas Christiansen |
Dato : 27-12-02 23:50 |
|
Thor Olsen skrev:
> Har lavet et lille Server - Client chat program i VB60 programmet
virker
> fint når jeg vil sende tekst. Men når jeg vil sende og modtage et
"array of
> byte" går det fløjten jeg læser kun værdien 0...
> Server.:
> Dim ByteArray(2) As Byte
> ByteArray(0) = 99
> ByteArray(1) = 99
> Wsck.SendData "PAKKE2"
> Wsck.SendData (ByteArray)
> Client.:
> Private Sub Wsck_DataArrival(ByVal bytesTotal As Long)
> Dim UdData As String
> Dim UdArray(4) As Byte
> Wsck.GetData UdData, vbString>
> If UdData = "PAKKE1" Then
> Wsck.GetData UdData, vbString>
> List1.AddItem UdData
> ElseIf UdData = "PAKKE2" Then
> Wsck.GetData UdArray, vbArray + vbByte
> MsgBox (UdArray(0) & Chr$(13) & UdArray(1))
For det første: Lad være med at sætte unødvendige parenteser omkring
parametre i procedure/metode-kald (du gør det i SendData, AddItem og
MsgBox).
Kun hvis du kalder en funktion eller hvis du kalder en procedure
v.hj.a.. Call, skal du bruge parenteser. Du kan komme ud i noget værre
snavs hvis du gør det og ikke har styr på hvilken effekt det har!
Jeg har prøvet at genskabe dit problem men det er faktisk ikke
lykkedes for mig. Husk at opdatere din VB6 (går jeg ud fra?) med
Service Pack 5 (altså Visual Basic/Visual Studio's Service Pack 5),
idet der i denne er rettet nogle fejl i Winsock kontrollen (som har
irriteret mig i årevis - fejlene altså).
En farbar vej til en løsning, tror jeg, er løseligt at diskutere
teorien bag TCP og UDP.
* Hvis du bruger UDP, får du sendt en pakke, men er der ingen garanti
for at den kommer frem, kun kommer frem én gang og/eller at den ikke
bliver dubleret undervejs.
* Hvis du bruger TCP, får du oprettet en to-vejs kommunikationskanal,
hvor der "garanteres" at pakkerne når frem, kun én gang og i korrekt
rækkefølge. Hvis denne garanti ikke kan overholdes, vil du få en
fejlmelding, så du er klar over at noget er gået galt.
De fleste vil nok være at bruge TCP, fordi de så slipper for selv at
sørge for at proppe kontroller ind i programmet og at implementere
genfremsendelser osv.
Der er bare lige det ved det, når man bruger TCP, at man får en
byte-orienteret kanal, og IKKE (som mange tror) en pakke-orienteret
kanal. Der er (når man bruger Winsock-kontrollen) ingen garanti for at
ens pakker ikke bliver hakket i småstykker, og ingen garanti for at
flere pakker ikke bliver sendt som én stor.
Man kan delvist styre noget af det, men det er ved at bruge DoEvents
og andre snavsede ting, som jeg slet ikke vil komme ind på.
Du er derimod garanteret at dine bytes kommer i den rigtige
rækkefølge, og dét er lige hvad de gør!
Når du sender med [.SendData "ABC"] er det netop ABC - og KUN ABC som
bliver sendt. Der er intet som fortæller modtageren at "nu slutter
strengen".
Du er med andre ord nødt til selv at bygge "noget" ind i din protokol,
som fortæller hvor data starter og slutter.
Èn måde at gøre det på er at afslutte data med en Chr(0), men det er
uheldigt, hvis dine byte-array's indeholder 0'er.
En anden måde kan være at præfikse alle data med et længefelt (sørg nu
for at det altid fylder samme antal bytes - brug f.eks. CLng).
Eksempel:
S = "Dette skal sendes"
.SendData CLng(Len(S))
.SendData S
Ved modtagelsen skal du så checke længdefeltet og læse nøjagtig så
mange bytes ind:
Dim L As Long, S As String
.GetData L, vbLong
.GetData S, vbString, L
Der er vel ingen som har sagt at det skulle være nemt?
Håber at du forstår essensen, eller må du spørge igen.
-------
Tomas
| |
mik (31-12-2002)
| Kommentar Fra : mik |
Dato : 31-12-02 12:29 |
|
"Tomas Christiansen" <toc-nospam-01@blikroer.dk> skrev i en meddelelse
news:auilek$2qmi$1@news.cybercity.dk...
> Thor Olsen skrev:
> > Har lavet et lille Server - Client chat program i VB60 programmet
> virker
> > fint når jeg vil sende tekst. Men når jeg vil sende og modtage et
> "array of
> > byte" går det fløjten jeg læser kun værdien 0...
>
> > Server.:
> > Dim ByteArray(2) As Byte
> > ByteArray(0) = 99
> > ByteArray(1) = 99
> > Wsck.SendData "PAKKE2"
> > Wsck.SendData (ByteArray)
>
> > Client.:
> > Private Sub Wsck_DataArrival(ByVal bytesTotal As Long)
> > Dim UdData As String
> > Dim UdArray(4) As Byte
> > Wsck.GetData UdData, vbString>
> > If UdData = "PAKKE1" Then
> > Wsck.GetData UdData, vbString>
> > List1.AddItem UdData
> > ElseIf UdData = "PAKKE2" Then
> > Wsck.GetData UdArray, vbArray + vbByte
> > MsgBox (UdArray(0) & Chr$(13) & UdArray(1))
>
> For det første: Lad være med at sætte unødvendige parenteser omkring
> parametre i procedure/metode-kald (du gør det i SendData, AddItem og
> MsgBox).
> Kun hvis du kalder en funktion eller hvis du kalder en procedure
> v.hj.a.. Call, skal du bruge parenteser. Du kan komme ud i noget værre
> snavs hvis du gør det og ikke har styr på hvilken effekt det har!
>
> Jeg har prøvet at genskabe dit problem men det er faktisk ikke
> lykkedes for mig. Husk at opdatere din VB6 (går jeg ud fra?) med
> Service Pack 5 (altså Visual Basic/Visual Studio's Service Pack 5),
> idet der i denne er rettet nogle fejl i Winsock kontrollen (som har
> irriteret mig i årevis - fejlene altså).
>
> En farbar vej til en løsning, tror jeg, er løseligt at diskutere
> teorien bag TCP og UDP.
>
> * Hvis du bruger UDP, får du sendt en pakke, men er der ingen garanti
> for at den kommer frem, kun kommer frem én gang og/eller at den ikke
> bliver dubleret undervejs.
>
> * Hvis du bruger TCP, får du oprettet en to-vejs kommunikationskanal,
> hvor der "garanteres" at pakkerne når frem, kun én gang og i korrekt
> rækkefølge. Hvis denne garanti ikke kan overholdes, vil du få en
> fejlmelding, så du er klar over at noget er gået galt.
>
> De fleste vil nok være at bruge TCP, fordi de så slipper for selv at
> sørge for at proppe kontroller ind i programmet og at implementere
> genfremsendelser osv.
>
> Der er bare lige det ved det, når man bruger TCP, at man får en
> byte-orienteret kanal, og IKKE (som mange tror) en pakke-orienteret
> kanal. Der er (når man bruger Winsock-kontrollen) ingen garanti for at
> ens pakker ikke bliver hakket i småstykker, og ingen garanti for at
> flere pakker ikke bliver sendt som én stor.
>
> Man kan delvist styre noget af det, men det er ved at bruge DoEvents
> og andre snavsede ting, som jeg slet ikke vil komme ind på.
>
> Du er derimod garanteret at dine bytes kommer i den rigtige
> rækkefølge, og dét er lige hvad de gør!
>
> Når du sender med [.SendData "ABC"] er det netop ABC - og KUN ABC som
> bliver sendt. Der er intet som fortæller modtageren at "nu slutter
> strengen".
> Du er med andre ord nødt til selv at bygge "noget" ind i din protokol,
> som fortæller hvor data starter og slutter.
>
> Èn måde at gøre det på er at afslutte data med en Chr(0), men det er
> uheldigt, hvis dine byte-array's indeholder 0'er.
> En anden måde kan være at præfikse alle data med et længefelt (sørg nu
> for at det altid fylder samme antal bytes - brug f.eks. CLng).
> Eksempel:
>
> S = "Dette skal sendes"
> .SendData CLng(Len(S))
> .SendData S
>
> Ved modtagelsen skal du så checke længdefeltet og læse nøjagtig så
> mange bytes ind:
>
> Dim L As Long, S As String
> .GetData L, vbLong
> .GetData S, vbString, L
>
> Der er vel ingen som har sagt at det skulle være nemt?
> Håber at du forstår essensen, eller må du spørge igen.
>
> -------
> Tomas
> Hej Tomas
Vil bare sige at det er et kanon godt svar du har skrevet - det er et, jeg
tager imod med kyshånd - selvom det ikke direkte var til mig
mik
| |
|
|