Newsgroup: it.comp.lang.visual-basic
Titolo: Trasferimanto coordinate via winsock

Sono riuscito a far passare di tutto tra due controlli winsock, ma le
coordinate di alcuni punti vanno a farsi friggere..
Mi spiego.
Ho una lavagna che trasmette le coordinate in remoto (è una lavagna
condivisa, come quella di NetMeeting).
Il codice è:
IN INVIO DATI:
Private Sub Picture1_MouseMove(Button As Integer, Shift As Integer, X As
Single, Y As Single)
On Error GoTo errore
If Button = vbLeftButton Then
    ws.SendData X & "§" & Y
    Picture1.Circle (X, Y), 10, vbBlack
    DoEvents
End If
errore:
If Err.Number = 40006 Then
    MsgBox "Impossibile disegnare. La lavagna remota è stata chiusa."
ElseIf Err.Number <> 0 Then
    MsgBox Err.Number & " " & Err.Description
End If
End Sub
Dove ws è il controllo winsock e § è un carattere di separazione.
IN RICEZIONE HO:
Private Sub ws_DataArrival(ByVal bytesTotal As Long)
Dim X As Single
Dim Y As Single
Dim Coordinate As Variant
    ws.GetData Coordinate, vbString
    Coordinate = Split(Coordinate, "§")
    X = CSng(Coordinate(0))
    Y = CSng(Coordinate(1))
    If X = -50 And Y = -50 Then
        Picture1.Cls
    Else
            Picture1.Circle (X, Y), 10, vbBlack
    End If
End Sub
In rete Lan a 10Mbit funziona a meraviglia.
Se provate infatti a collegarvi al vostro stesso ip, il disegno è perfetto.
Ma come mi sposto fuori, allora iniziano i problemi.
Infatti non arrivano tutti i punti ma se ne perdono per strada circa il 90%
Da cosa può dipendere? tenete conto che ho fatto prove anche fra utenti
fastweb a 10Mbit/sec, quindi non credo che sia problema in velocità di
trasmissione...
bye
-- 
Esistono 10 tipi di persone: chi conosce il binario e chi no.
www.nicolaottomano.it

 coordinate di alcuni punti vanno a farsi friggere..
[CUT]
sei in udp o tcp?
Flippo

 coordinate di alcuni punti vanno a farsi friggere..
Il mousemove avviene, se ovviamente si muove il mouse, in continuazione, per
cui se non metti un carattere di terminazione (possibilmente diverso dal
separatore), rischi di avere la concatenazione di Y con l'X successivo.
Ciao
Alberto

> sei in udp o tcp?
TCP


 concatenazione di Y con l'X successivo.
Ed č proprio quella la mia paura....
Devo vedere come gestire una cosa del genere....
Hai per caso qualche esempio sottomano?


 bye
byez

 Hai per caso qualche esempio sottomano?
Esempi no.
Però in invio:
    ws.SendData CStr(X) & "§" & CStr(Y) & chr$(3)
E in ricezione (ogni cosa che ricevi la appendi in coda ad un buffer stringa
e poi lo valuti):
Pos_ETX = instr(Buffer_Ricezione,Chr$(3))
If Pos_Etx>0 then
    Stringa_Valida=left$(buffer_ricezione,pos_etx-1)
    Buffer_Ricezione=right$(buffer_ricezione, len(buffer_ricezione)-pos_etx)
    'qui valuti stringa_valida, splittandola col separatore e facendo il val
delle due stringhe...
End if
Ciao
Alberto

L'idea di Alberto mi piace, credo che userň il buffer..
cmq grazie per il consiglio.


La tua idea del buffer ha diminuito gli errori in ricezione del 20% circa...
Per maggiore sicurezza in invio faccio una cosa del genere:
    Picture1.Circle (X, Y), 10, vbBlack
    ws.SendData X & "§" & Y & "#"
    DoEvents
    ws.SendData X & "§" & Y &  "#"
    DoEvents
    ws.SendData X & "§" & Y &  "#"
In questo modo arrivano a destinazione il 50% dei punti.
Di ogni punto spedisco 3 copie, quindi è come se arrivassero a destinazione
solo il 16% dei pacchetti inviati....
Mi sembra un pò poco... però il risultato non è male (tenendo conto che
prima arrivava forse l'1% dei punti...).
*Ora la mia domanda è questa:*
Il DoEvents che metto fra un invio e l'altro è utile o al contrario può
essere dannoso?


 può essere dannoso?
Quella del buffer non è una mia idea, ma la base delle comunicazioni
asincrone, qualunque sia la tecnologia.
Se la porta è aperta correttamente, e non ci sono problematiche di rete,
devono arrivare TUTTI i messaggi.
Anche il 90% sarebbe poco.
Posta il codice con cui gestisci la ricezione, perchè in invio mi sembra
tutto a posto.
Ciao
Alberto

 sembra tutto a posto.
Questo č il codice con cui gestisco l'invio dei dati della lavagna:
Private Sub ws_DataArrival(ByVal bytesTotal As Long)
Dim X As Single
Dim Y As Single
Dim pos_etx As Long
Dim Coordinate As Variant
    Coordinate = "###"
    ws.GetData Buffer_Ricezione, vbString
    pos_etx = InStr(Buffer_Ricezione, "#")
    If pos_etx > 0 Then
        Coordinate = Left$(Buffer_Ricezione, pos_etx - 1)
        Buffer_Ricezione = Right$(Buffer_Ricezione, Len(Buffer_Ricezione) -
pos_etx)
    End If
    If Coordinate <> "###" Then
        Coordinate = Split(Coordinate, "§")
        X = CSng(Coordinate(0))
        Y = CSng(Coordinate(1))
        If X = -50 And Y = -50 Then
            Picture1.Cls
        Else
            Picture1.Circle (X, Y), 10, vbBlack
        End If
    End If
End Sub


 stringa e poi lo valuti):
Appendere in coda = Concatenazione -> &
Altrimenti, a cosa servirebbe:
Buffer_Ricezione = Right$(Buffer_Ricezione, Len(Buffer_Ricezione) -pos_etx)
Ciao
Alberto

C@%%o è vero!
Mannaggia alla miseria!
Ora modifico e ti faccio sapere.
bye


> Ora modifico e ti faccio sapere.
stasera devo provare con un amico che è nel NAT di fastweb.
Come provo, posto il risultato sul NG.
Comunque il codice ora è:
Private Sub ws_DataArrival(ByVal bytesTotal As Long)
Dim X As Single
Dim Y As Single
Dim pos_etx As Long
Dim DatiRicevuti As String
Dim Coordinate As Variant
    Coordinate = "###"
    ws.GetData DatiRicevuti, vbString
    Buffer_Ricezione = Buffer_Ricezione & DatiRicevuti
    pos_etx = InStr(Buffer_Ricezione, "#")
    If pos_etx > 0 Then
        Coordinate = Left$(Buffer_Ricezione, pos_etx - 1)
        Buffer_Ricezione = Right$(Buffer_Ricezione, Len(Buffer_Ricezione) -
pos_etx)
    End If
    If Coordinate <> "###" Then
        Coordinate = Split(Coordinate, "§")
        X = CSng(Coordinate(0))
        Y = CSng(Coordinate(1))
        If X = -50 And Y = -50 Then
            Picture1.Cls
        Else
            Picture1.Circle (X, Y), 10, vbBlack
        End If
    End If
End Sub
Che ne dici?


     End If
Ma questo pezzo di codice viene eseguito UNA sola volta:
se tu sul tuo pc munoi il mouse vengono spedite 5-10-40 coppie di 
coordinate:
"x1§y1#x2§y2#....#xn§yn#"
tu in questo caso stai recuperando SOLO x1 e y1... dovresti fare come ti 
abbiamo detto un bello split per "#" e poi usare tutto l'array splittato 
per ricavarti le xy:
nell'evento data_arrival:
Dim S as String
Dim V() as String
Dim XY() as String
Dim I as Integer
    Winsock1.GetData S, vbString
    V=Split(S,"#")
    For I=0 to Ubound(V)
      XY=Split(V(I),"§")
      Disegna(XY(0), XY(1))
    Next I
End Sub

 Ma questo pezzo di codice viene eseguito UNA sola volta:
Hai ragione.
In effetti andrebbe inserito in un loop che va fino a che Pos_Etx=0.
Lo split č solamente una versione diversa della stessa cosa (con un for
anzichč un loop).
L'importante č che l'elemento piů alto dell'array, se incompleto, deve
essere lasciato nella stringa residua, per essere completato al Data_Arrival
successivo.
Ciao
Alberto


Rivedo un po' il codice che avevo postato:
Pos_ETX = instr(Buffer_Ricezione,Chr$(3))
do while Pos_Etx>0
    Stringa_Valida=left$(buffer_ricezione,pos_etx-1)
    Buffer_Ricezione=right$(buffer_ricezione, len(buffer_ricezione)-pos_etx)
    'qui valuti stringa_valida, splittandola col separatore e facendo il val
delle due stringhe...
    Pos_ETX = instr(Buffer_Ricezione,Chr$(3))
Loop
Ciao
Alberto

 Loop
In effetti hai ragione, mi ero accorto che il buffer cresceva a dismisura e
stavo cercando una soluzione... che era proprio un do while...
Il problema che ho è che i pacchetti vengono inviati e non si aspetta, per
forza di cose, la risposta del pc remoto.
Mentre per l'invio files (dove la precisione deve essere assoluta) invio un
pezzo del file e aspetto al risposta. se questa non arriva ripeto l'invio.
ora devo andare in università. quando torno stasera apporto le dovute
modifiche e vi faccio sapere..
bye
