Oppure

Loading
06/05/09 19:22
acromangelo
Mi ripresento a voi con un nuovo problema che mi ha fatto disperare per 3 giorni consecutivi:
ho un client e un server connessi tra di loro. uno deve inviare all'altro un'immagine e usa questo tipo di invio

Dim NextPart as Boolean

Private Function InviaImmagine()
Dim FileLength As Long, Temp As String, PackageSize As Long, LastData As Boolean
FileLength = FileLen(App.path & "\immagine.jpg")
NextPart = False
Main.wsk.SendData "FILE||0"
PackageSize = 2048
LastData = False
FF = FreeFile
Open App.path & "\immagine.jpg" For Binary Access Read As #FF
Temp = ""
Do Until EOF(FF)
    If FileLength - Loc(FF) <= PackageSize Then
        PackageSize = FileLength - Loc(FF) + 1
        LastData = True
    End If
    Temp = Space$(PackageSize)
    Get FF, , Temp
    Do While NextPart = False
        DoEvents
    Loop
    NextPart = False
    If LastData = True Then
        Temp = Mid(Temp, 1, Len(Temp) - 1)
    End If
    Main.wsk.SendData "FILE||1||" & Temp
Loop
Do While NextPart = False
    DoEvents
Loop
NextPart = False
Close FF
Kill App.path & "\immagine.jpg"
Main.wsk.SendData "FILE||2"
End Function

Private Sub wsk_SendComplete()
NextPart = True
End Sub


e questo tipo di ricezione

Private Sub wsk_DataArrival(ByVal bytesTotal As Long)
Dim Incoming as string, Parsed() as string, FF as integer
wsk.GetData Incoming
animazione = True
Parsed = Split(Incoming, "||")
If Parsed(0) = "FILE" Then
If Parsed(1) = "0" Then
    FF = FreeFile
    Open App.Path & "\immagine.jpg" For Binary Access Write As #FF
    FileBar.Max = Parsed(2)
    FileBar.Min = 0
    FileBar.Value = 0
ElseIf Parsed(1) = "1" Then
    Put #FF, , Parsed(2)
    If Not (FileBar.Value + bytesTotal) > FileBar.Max Then FileBar.Value = FileBar.Value + bytesTotal
ElseIf Parsed(1) = "2" Then
    Close #FF
    picImmagine.Picture = LoadPicture(App.Path & "\immagine.jpg")
    Kill App.Path & "\immagine.jpg"
    FileBar.Value = 0
End If
End If
End Sub


Ecco, il codice funziona alla perfezione, ma l'immagine arriva tutta a casaccio, come se i pezzi di immagine arrivassero a caso, e la cosa strana è che non avviene sempre...poche volte invece l'immagine arriva perfettamente. Potreste aiutarmi cercando di capire il motivo di questi errori?
PS: questo tipo di metodo per inviare un file l'ho già usato in un programma di scambio files e li funziona perfettamente sempre.

Grazie in anticipo
Ultima modifica effettuata da acromangelo 06/05/09 19:26
aaa
06/05/09 19:44
theprogrammer
Il programma si basa sul riconoscimento dei due caratteri

||

per indicare l'inizio dello stesso ...

Ma questi due caratteri si possono presentare all'interno di un file binario lungo e complesso come un'immagine.

A seconda dei casi quindi (se nell'immagine quella coppia di byte appare piu' volte) il programma che riceve potrebbe essere "ingannato" e i dati non interpretati correttamente.

Prova a cambiare quella sequenza e renderla piu' complessa ...
aaa
06/05/09 20:16
acromangelo
Appena ho letto la tua risposta ho pensato che quasi sicuramente sarebbe stato quello...ma poi provandolo ho verificato che anche cambiando "||" con "|ødividø|" non cambiava nulla...

l'errore rimane =(
aaa
07/05/09 6:56
theprogrammer
Allora posta il progetto zippato e un file (un jpg) che ti da' il problema.

Provero' il tuo programma proprio con quel file per capire dove sta l'errore ...

(al limite posta il link di un sito da cui scaricare quello che ti ho detto).
aaa
07/05/09 14:15
acromangelo
Eccolo quà...non so più che fare :(
Ultima modifica effettuata da acromangelo 07/05/09 14:17
aaa
07/05/09 20:47
theprogrammer
Ho visto meglio il codice e ho trovato il problema ...

Quel codice da' per scontato il fatto che i pacchetti che vengono inviati, siano ricevuti cosi' come sono inviati all'interno di un evento DataArrival.

Per le comunicazioni TCP, non e' cosi'. E non e' una cosa da poco. E' il motivo per cui hai (a volte) quel comportamento.

Per capirci, l'evento DataArrival puo' essere richiamato dopo che ha ricevuto un certo numero di byte DIVERSO da quello che ti aspetti. E dato che in quell'evento tu tratti solamente quelli che ti aspetti, quelli in piu' vengono persi e l'immagine non e' quella di partenza.


aaa
08/05/09 16:08
acromangelo
mmm ho capito...e allora mi spiegheresti perchè questo altro programma che ho fatto funziona alla perfezione anche se ha lo stesso tipo di invio?
aaa
09/05/09 7:20
theprogrammer
Postato originariamente da acromangelo:

mmm ho capito...e allora mi spiegheresti perchè questo altro programma che ho fatto funziona alla perfezione anche se ha lo stesso tipo di invio?


Non e' vero.

Anche questo programma presenta gli stessi problemi.

Ho provato a trasferire un file da poco piu' di 15 M e il file trasferito era diverso sia nella sequenza di byte sia (addirittura) nella grandezza ...

Il trasferimento Winsock non e' un mistero. Se devi scrivere un programma "affidabile" basta tenere conto delle regole del TCP ...

La regola fondamentale e' tenere SEMPRE presente il fatto che nell'evento DataArrival possono essere letti piu' (o anche meno) dati di quello che ti aspetti. Quando leggi la stringa di dati in arrivo nell'evento, devi trattarla TUTTA, dall'inizio alla fine.
aaa