Visualizzazione dei risultati da 1 a 9 su 9
  1. #1

    [VB.NET]: Inviare file da client a server

    Salve, è da molto che non programmo in vb.net e infatti sono parecchio arrugginito...

    Ho realizzato l'applicazione client server ke legge i dati ed ho creato una seconda istanza del client e server per la ricezione dei file... solo ke provando con un file xls di 9kb, il programma sembra inviare tutto ma il server riceve solo 8kb...

    quindi c'è qualkosa che non va...
    qui il codice del server:

    codice:
    Imports System.Net.Sockets
    Imports System.Text.Encoding
    
    
    Public Class frmMain
    
        Private client As New TcpClient
        Private fileClient As New TcpClient
        Private server As New TcpListener(1989)
        Private fileServer As New TcpListener(1001)
        Private NetStream, NetFile As NetworkStream
        'Percorso su cui salvare il file
        Private FileName As String
        'Dimensione del file
        Private FileSize As Int64
    
    
        Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            server.Start()
            tmrControlConnection.Start()
    
    
        End Sub
    
    
        Private Sub Send(ByVal Msg As String, ByVal Stream As NetworkStream)
            'Se si può scrivere
            If Stream.CanWrite Then
                'Converte il messaggio in binario
                Dim Bytes() As Byte = ASCII.GetBytes(Msg)
                'E lo scrive sul network stream
                Stream.Write(Bytes, 0, Bytes.Length)
            End If
        End Sub
    
        'Ottiene un messaggio dallo stream di rete
        Private Function GetMessage(ByVal Stream As NetworkStream) As String
            'Se si può leggere
            If Stream.CanRead Then
                Dim Bytes(client.ReceiveBufferSize) As Byte
                Dim Msg As String
                'Legge i bytes arrivati
                Stream.Read(Bytes, 0, Bytes.Length)
                'Li converte in una stringa leggibile
                Msg = ASCII.GetString(Bytes)
                'E restituisce la stringa
                Return Msg.Normalize
            Else
                Return Nothing
            End If
        End Function
    
        Function replaceEntity(ByVal str As String)
            Return Replace(str, "à", "a")
        End Function
    
    
    
        Private Sub tmrControlConnection_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrControlConnection.Tick
            'Se ci sono connessioni in attesa...
            If server.Pending Then
                'Ferma il timer per eseguire le operazioni
                tmrControlConnection.Stop()
                lblStatus.Text = "È stata ricevuta una richiesta ..."
                'Accetta la connessione
                client = server.AcceptTcpClient
                'Apre lo stream di rete condiviso
                NetStream = client.GetStream
                'Termina l'ascolto
                server.Stop()
                'Inizia la ricezione di messaggi
                tmrGetData.Start()
                lblStatus.Text = "STATO: Connesso"
            End If
    
        End Sub
    
        Private Sub tmrControlFile_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrControlFile.Tick
            'Se c'è una richiesta, l'accetta subito
            If fileServer.Pending Then
                tmrControlFile.Stop()
                fileClient.ReceiveBufferSize = 1024
                fileClient = fileServer.AcceptTcpClient
                NetFile = fileClient.GetStream
                'Ferma il listener
                fileClient.ReceiveBufferSize = 1024
                fileServer.Stop()
                lblStatus.Text = "Flusso di informazioni aperto ..."
                'Attiva la ricezione di dati attraverso un background worker
                bgReceiveFile.RunWorkerAsync()
            End If
    
        End Sub
    
        Private Sub tmrGetData_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrGetData.Tick
            If client.Connected And client.Available Then
                'Ferma il timer mentre si eseguono le operazioni
                tmrGetData.Stop()
                'Legge il messaggio
                Dim Msg As String = GetMessage(NetStream)
    
                If Msg.StartsWith("ConfirmTransfer") Then
                    'Divide il messagio in parti in base al carattere pipe
                    Dim Parts() As String = Msg.Split("|")
                    'La prima parte è "ConfirmTransfer"
                    'La seconda è il percorso del file sull'altro computer
                    Dim File As String = Parts(1)
                    'La terza è la dimensione
                    Dim Size As Int64 = CType(Parts(2), Int64)
                    'Ottiene solo il nome del file, senza percorso
                    File = IO.Path.GetFileName(File)
                    'Costruisce il percorso del file su questo computer,
                    'salvandolo nella cartella del progetto (bin\Debug)
                    FileName = "C:\" & replaceEntity(File)
                    'Imposta Size come variabile globale
                    FileSize = Size
    
                    'Manda OK al client
                    Send("OK", NetStream)
                    'Intanto si mette in attesa sulla porta 1001 per
                    'l'invio dei bytes del file
                    fileServer.Start()
                    'E attiva il timer di controllo
                    tmrControlFile.Start()
    
                End If
                'Riprende il controllo
                tmrGetData.Start()
            End If
    
        End Sub
    
      
    
        Private Sub bgReceiveFile_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgReceiveFile.DoWork
            'Apre un nuovo stream in base al percorso costruito
            'nella procedura precedente
            Dim Stream As New IO.FileStream("C:\prova.xlsx", IO.FileMode.Create)
            'Crea un indice che indica il progresso
            Dim Index As Int64 = 0
    
            lblStatus.Text = "In ricezione ..."
    
            For Block As Int64 = 0 To FileSize Step 8192
    
    
                If fileClient.Available Then
                    'Riceve i bytes necessari
                    Dim Bytes(8192) As Byte
                    Dim Msg As String = GetMessage(NetFile)
                    'Se i bytes sono un messaggio stringa e contengono
                    '"END", oppure la dimensione giusta è già stata
                    'raggiunta, allora si ferma
                    If Msg.Contains("END") Then
                        Exit For
                    End If
                    'Preleva i bytes dallo stream di rete
                    NetFile.Read(Bytes, 0, 8192)
    
    
                    'E li scrive sul file fisico
                    Stream.Write(Bytes, 0, 8192)
                    'Incrementa l'indice di 8192
                    Index += 8192
                    'E notifica il progresso
                    bgReceiveFile.ReportProgress(Index * 100 / FileSize)
                End If
            Next
    
    
            lblStatus.Text = "File ricevuto ..."
            Stream.Close()
        End Sub
    
        Private Sub bgReceiveFile_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgReceiveFile.ProgressChanged
            prgProgress.Value = e.ProgressPercentage
        End Sub
    End Class

    Cosa sbaglio?

  2. #2
    se vi interessa qui anke il codice del client:

    codice:
    Imports System.Net.Sockets
    Imports System.Text.ASCIIEncoding
    
    
    
    Public Class frmMain
        'Client: il client che si dovrà connettere al server
        'FileSender: il client che ha il compito di trasferire i
        '   pacchetti di informazioni al server
        Private Client, FileSender As TcpClient
        'NetStream: lo stream su cui scrivere i dati di comunicazione
        'NetFile: lo stream per inviare i dati da scrivere sul file
        Private NetStream, NetFile As NetworkStream
        'L'IP del server a cui connettersi
        Private IP As String
    
        'Invia un messaggio su uno stream di rete
        Private Sub Send(ByVal Msg As String, ByVal Stream As NetworkStream)
            'Se si può scrivere
            If Stream.CanWrite Then
                'Converte il messaggio in binario
                Dim Bytes() As Byte = ASCII.GetBytes(Msg)
                'E lo scrive sul network stream
                Stream.Write(Bytes, 0, Bytes.Length)
            End If
        End Sub
    
        'Ottiene un messaggio dallo stream di rete
        Private Function GetMessage(ByVal Stream As NetworkStream) As String
            'Se si può leggere
            If Stream.CanRead Then
                Dim Bytes(Client.ReceiveBufferSize) As Byte
                Dim Msg As String
                'Legge i bytes arrivati
                Stream.Read(Bytes, 0, Bytes.Length)
                'Li converte in una stringa leggibile
                Msg = ASCII.GetString(Bytes)
                'E restituisce la stringa
                Return Msg.Normalize
            Else
                Return Nothing
            End If
        End Function
    
        
        Private Sub btnConnetti_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnetti.Click
            'Ottiene l'IP del server
            IP = "127.0.0.1"
    
            'Inizializza un nuovo client
            Client = New TcpClient
            'E tenta la connessione all'IP dato, sulla porta 25
            stsStato.Text = "Connessione in corso..."
            Try
                Client.Connect(IP, 1989)
            Catch SE As SocketException
                MessageBox.Show("Impossibile stabilire una connessione!", _
                Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                Exit Sub
            End Try
            'Se la connessione è riuscita, ottiene lo
            'stream condiviso di rete direttamente collegato con
            'il networkstream del server
            If Client.Connected Then
                'Ora si è sicuri di essere connessi:
                'sblocca i comandi per il trasferimento
                NetStream = Client.GetStream
                stsStato.Text = "Connessione riuscita ..."
            End If
    
        End Sub
    
        Private Sub btnFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFile.Click
            opFile.Filter = "Tutti i file|*.*"
            If opFile.ShowDialog = Windows.Forms.DialogResult.OK Then
                txtFile.Text = opFile.FileName
            End If
    
        End Sub
    
        Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
            If Not IO.File.Exists(txtFile.Text) Then
                MessageBox.Show("Il file non esiste ...", Me.Text, _
                MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                Exit Sub
            End If
    
            'Se si è connessi e si può scrivere
            'sullo stream di rete...
            If Client.Connected AndAlso NetStream.CanWrite Then
                'Manda un messaggio al server, chiedendo
                'conferma del trasferimento. Nel messaggio immette anche
                'alcune informazioni riguardo il nome e la
                'dimensione del file
                Dim Msg As String = _
                    String.Format("ConfirmTransfer|{0}|{1}", txtFile.Text, _
                    FileLen(txtFile.Text))
                'Invia il messaggio con la procedura scritta sopra
                Send(Msg, NetStream)
    
                'Attiva il timer per controllare i dati arrivati
                tmrGetData.Start()
                'Disattiva il pulsante per evitare più azioni
                'contemporanee indesiderate
                stsStato.Text = "In attesa di conferma dal server..."
            End If
    
        End Sub
    
        Private Sub tmrGetData_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrGetData.Tick
            If Client.Connected AndAlso Client.Available Then
                'Ferma il timer mentre si eseguono le operazioni
                tmrGetData.Stop()
                'Legge il messaggio
                Dim Msg As String = GetMessage(NetStream)
    
                'Uso Contains per un semplice motivo. Quando si converte
                'un array di bytes in una stringa, ci possono essere
                'caratteri speciali successivi a questa, come ad esempio
                'il NULL terminator (carattere 00), che ne compromettono
                'la struttura. 
                If Msg.Contains("OK") Then
                    'Termina questa connessione e si connette
                    'alla porta deputata alla ricezione dei file
                    FileSender = New TcpClient
                    FileSender.Connect(IP, 1001)
                    If FileSender.Connected Then
                        'Ottiene lo stream associato a questa operaizone
                        NetFile = FileSender.GetStream
                        'E inizia la trasmissione dei dati
                        bgSendFile.RunWorkerAsync(txtFile.Text)
                    End If
                End If
    
                'Riprende il controllo dei dati
                tmrGetData.Start()
            End If
    
        End Sub
    
       
    
        Private Sub bgSendFile_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.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 8192 posti. Il file viene spedito in
            '"pacchettini" per evitare di sovraccaricare la connessione
            Dim Bytes(8192) As Byte
    
            'Se il file è più grande di 8KiB, lo divide
            'in blocchi di dati da 8192 bytes
            If Size > 8192 Then
                For Block As Int64 = 0 To Size Step 8192
                    'Se i bytes rimanenti sono più di 8192,
                    'ne legge un blocco intero
                    If Size - Block >= 8192 Then
                        Reader.Read(Bytes, 0, 8192)
                    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, 8192)
    
                    'Riporta la percentuale all'utente
                    bgSendFile.ReportProgress(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(100)
                Next
            Else
                'Se il file è minore di 8KiB, lo invia tutto
                'direttamente dal server
                Reader.Read(Bytes, 0, Size)
                NetFile.Write(Bytes, 0, Size)
            End If
            Reader.Close()
    
            'Percentuale massima: lavoro terminato
            bgSendFile.ReportProgress(100)
            Threading.Thread.Sleep(100)
            'Comunica la fine delle operazioni
            'NetFile.Write(ASCII.GetBytes("END"), 0, 3)
            stsStato.Text = "File inviato con successo ..."
        End Sub
    
        Private Sub bgSendFile_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgSendFile.ProgressChanged
            prgProgress.Value = e.ProgressPercentage
        End Sub
    End Class

  3. #3
    Utente di HTML.it
    Registrato dal
    Jun 2009
    Messaggi
    77
    ma scusa che errore ti da ??????????????????????????

  4. #4
    Errori nessuno, ma salva un file da 8kb... si perde dati strada facendo...

    Ho provato a mandare 9kb, 11kb... niente si ferma ad 8kb... c'è qualke errore sicuramente... ma non lo trovo...

  5. #5
    Nessuna novità ragazzi?

    Vi do altri dettagli sul problema...

    Se mando un file piu piccolo del chunk, ovvero 8kb... il file arriva vuoto... o meglio il server salva un file di 0kb... ma il client lo invia bene visto ke la progressbar arriva a 100% tramite calcolo dei dati inviati ...

    se invio file piu grossi del chunk viene ricevuto solo il secondo chunk di 8kb, infatti confrontando i file, noto ke mancano 8kb di inizio, poi ci sono gli 8kb del secondo chunk e poi manca tutto il resto nel file ke mi salva il server...

    cosa sbaglio?

  6. #6
    Utente di HTML.it
    Registrato dal
    Jun 2009
    Messaggi
    77
    ho notato che non arriva niente con il tuo codice al serve per lo meno non salva niente si pianta crash e non va avanti il client funce perfettamente ma il serve si inceppa non capisco dove sia il problema visto che nel debug non da segni di errore secondo me manca un passaggio

  7. #7
    Allora:

    ho creato una condizionale ed ho messo ke se FileSize è minore del chunk, scrive il file al volo... quindi risolto il problema dei file piu piccoli di 8kb, funziona perfettamente...

    Invece per i file più grandi, noto ke facendo un debug.print di bytes.lenght dal client ottengo i dati inviati correttamente + 1 byte nullo alla fine per ogni chunk... quindi 8193

    mentre il server ottiene i primi da 8192 e l'ultimo da 3 bytes...

  8. #8
    Utente di HTML.it
    Registrato dal
    Jun 2009
    Messaggi
    77
    'E li scrive sul file fisico
    Stream.Write(Bytes, 0, 8192)


    sostituisci il 0 con index

  9. #9
    Niente da fare, non arrivano proprio i dati infatti non è cambiato nulla...

    se a te funziona forse hai modificato qualkos'altro anke...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.