Oppure

Loading
07/03/10 20:43
oretovalley
Ciao a tutti, studiando dalla guida di Il Totem, mi sono imbattuto in questo problema, stavo provando a inserire nuove funzioni nel codice, quale annullare l'invio di un file, solo che non riesco a far capire al server che ho annullato l'operazione dal client, ho provato ad inviare tramite il client un messaggio al server, ma sembra che non lo riceve.

Il codice del Client:
Private Sub bgSendFile_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles bgSendFile.DoWork
        'Ottiene il nome del file dall'argomento passato al metodo
        'RunWorkerAsync nella procedura precedente
        Dim FileName As String = e.Argument
        'Crea un nuovo lettore del file a basso livello, così
        'da poter ottenere bytes di informazione anziché caratteri
        'come nello StreamReader
        Dim Reader As New IO.FileStream(FileName, IO.FileMode.Open)
        'Calcola la grandezza del file, per poter poi tenere
        'l'utente al corrente della percentuale di completamento
        Dim Size As Int64 = FileLen(FileName)
        'Un blocco di bytes da 4096 posti. Il file viene spedito in
        '"pacchettini" per evitare di sovraccaricare la connessione
        Dim Bytes(4095) As Byte

        'Se il file è più grande di 4KiB, lo divide
        'in blocchi di dati da 4096 bytes
        If Size > 4096 Then
            For Block As Int64 = 0 To Size Step 4096
                'Se i bytes rimanenti sono più di 4096,
                'ne legge un blocco intero
                If Size - Block >= 4096 Then
                    Reader.Read(Bytes, 0, 4096)
                Else
                    'Altrimenti un blocco più piccolo
                    Reader.Read(Bytes, 0, Size - Block)
                End If
                'Scrive i dati prelevati sullo stream di rete,
                'inviandoli così al server
                NetFile.Write(Bytes, 0, 4096)
                'Riporta la percentuale all'utente
                prgProgress.Value = Block * 100 / Size
                'Smette per 30ms, così da dare tempo dal
                'server di poter processare i pacchetti uno per
                'uno, evitando confusione
                Threading.Thread.Sleep(30)

                If bgSendFile.CancellationPending Then 'If user abort download
                    NetFile.Write(ASCII.GetBytes("STOP"), 0, 4)
                    Exit For
                End If

            Next
        ElseIf Size < 4096 Then
            'Se il file è minore di 4KiB, lo invia tutto
            'direttamente dal server
            Reader.Read(Bytes, 0, Size)
            NetFile.Write(Bytes, 0, Size)
        End If
        Reader.Close()

        If bgSendFile.CancellationPending Then 'If user abort download            
            MsgBox("Invio Annullato", MsgBoxStyle.Critical)
        Else
            'Percentuale massima: lavoro terminato
            bgSendFile.ReportProgress(100)
            Threading.Thread.Sleep(100)
            'Comunica la fine delle operazioni
            NetFile.Write(ASCII.GetBytes("END"), 0, 3)
            MsgBox("File inviato con successo!", MsgBoxStyle.Information)
            cmdSend.Enabled = True
        End If
    End Sub


Il codice del server:
Private Sub bgReceiveFile_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles bgReceiveFile.DoWork
        'Apre un nuovo stream in base al percorso costruito
        'nella procedura precedente
        Dim Stream As New IO.FileStream(FileName, IO.FileMode.Create)

        Dim safedelegate As New ChangeTextsSafe(AddressOf ChangeTexts)
        Me.Invoke(safedelegate, 0) 'Invoke the TreadsafeDelegate

        'Crea un indice che indica il progresso
        Dim Index As Int64 = 0
        Dim speedtimer As New Stopwatch
        Dim currentspeed As Double = -1
        Dim readings As Integer = 0

        lblStatus.Text = "In ricezione..."
        Do
            If FileReceiver.Available Then

                speedtimer.Start()

                'Riceve i bytes necessari
                Dim Bytes(4096) As Byte
                Dim Msg As String = ASCII.GetString(Bytes)
                'Se i bytes sono un messaggio stringa e contengono
                '"END", oppure la dimensione giusta è già stata
                'raggiunta, allora si ferma
                If Msg.Contains("END") Or Msg.Contains("STOP") Or Index >= FileSize Then
                    Exit Do
                End If
                'Preleva i bytes dallo stream di rete
                NetFile.Read(Bytes, 0, 4096)
                'E li scrive sul file fisico
                Stream.Write(Bytes, 0, 4096)
                'Incrementa l'indice di 4096
                Index += 4096
                'E notifica il progresso
                bgReceiveFile.ReportProgress(Index * 100 / FileSize)

                lblStatus.Text = prgProgress.Value & " %"

                Me.Invoke(safedelegate, currentspeed)

                readings += 1
                If readings >= 5 Then 'For increase precision, the speed it's calculated only every five cicles
                    currentspeed = 20480 / (speedtimer.ElapsedMilliseconds / 1000)
                    speedtimer.Reset()
                    readings = 0
                End If

            End If

        Loop

        lblStatus.Text = "File ricevuto!"
        Stream.Close()
        MessageBox.Show("File ricevuto con successo!", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Information)
        lblStatus.Text = ""
    End Sub


se stoppo il file dal client, la condizione mi dice che esce dal Do, è mi dovrebbe dire automaticamente, File Ricevuto, almeno per ora, ma rimane fermo. Come posso fare?
aaa
08/03/10 17:31
Il Totem
E' possibile che prima di Stop ci sia un byte nullo che tronca la stringa. Evita di mandare messaggi sui socket deputati all'invio/ricezione di dati. Usa piuttosto i tcp client di controllo.
Ultima modifica effettuata da Il Totem 08/03/10 17:32
aaa