Jo,
wie @radio-ffk versprochen hier mal der Code, um eine Datei über TCP zu versenden. Dafür wird die Datei in kleine Pakete eingeteilt und dann häppchenweise verschickt. Das hat den Vorteil, dass wird nicht die komplette Datei in den Arbeitsspeicher laden müssen. Ein Beispielprojekt ist im Anhang. Die Idee stammt von hier. Viel Spaß
Client, Senden:
Server, Empfangen:
wie @radio-ffk versprochen hier mal der Code, um eine Datei über TCP zu versenden. Dafür wird die Datei in kleine Pakete eingeteilt und dann häppchenweise verschickt. Das hat den Vorteil, dass wird nicht die komplette Datei in den Arbeitsspeicher laden müssen. Ein Beispielprojekt ist im Anhang. Die Idee stammt von hier. Viel Spaß
Client, Senden:
VB.NET-Quellcode
- Const BufferSize = 1024
- Private Async Sub SendButton_Click(sender As Object, e As EventArgs) Handles SendButton.Click
- Dim port As Integer
- 'Erstmal überprüfen wir die Benutzereingaben
- If String.IsNullOrWhiteSpace(IpTextBox.Text) Then
- MessageBox.Show("Bitte geben Sie eine IP-Adresse ein", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)
- Return
- End If
- If Not Integer.TryParse(PortTextBox.Text, port) OrElse (port < 1 OrElse port > 65535) Then
- MessageBox.Show("Bitte geben Sie einen gültigen Port ein", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)
- Return
- End If
- 'Wenn alles ok ist, deaktivieren wir alle Buttons
- SendButton.Enabled = False
- IpTextBox.Enabled = False
- PortTextBox.Enabled = False
- SelectPathButton.Enabled = False
- Dim tcpClient As New TcpClient
- StatusLabel.Text = "Verbinde zu Server..."
- Try
- Await tcpClient.ConnectAsync(IpTextBox.Text, port) 'Wir versuchen, eine Verbindung zu dem Server aufzubauen
- Catch ex As SocketException
- MessageBox.Show("Es konnte keine Verbindung zu dem Server hergestellt werden") 'Wenn das nicht klappt, sagen wir das dem Benutzer und brechen ab
- ResetSending()
- Return
- End Try
- Using binaryWriter = New BinaryWriter(tcpClient.GetStream()) 'BinaryWriter sind das beste. Also instanziieren wir uns einen
- Using fs = New FileStream(PathTextBox.Text, FileMode.Open, FileAccess.Read) 'und wir öffnen die Datei mit Rechten zum Auslesen
- Dim packets = Convert.ToInt32(Math.Ceiling(fs.Length / BufferSize)) 'Wir berechnen, wie viele Pakete wir brauchen werden. Ein Paket kann maximal die Größe des Buffers haben
- Dim remainingBytes = CInt(fs.Length) 'Die Anzahl der Bytes, die wir noch versenden müssen
- StatusProgressbar.Maximum = packets
- binaryWriter.Write(remainingBytes) 'Wir fangen an, indem wir dem Server die Größe der Datei mitteilen
- For i = 0 To packets - 1
- Dim currentPacketLength As Integer 'Dies ist die Größe des aktuellen Paketes, welches wir verschicken wollen
- If remainingBytes > BufferSize Then 'Wenn noch genug Bytes für ein volles Paket da sind, nehmen wir direkt die Größe...
- currentPacketLength = BufferSize
- remainingBytes -= currentPacketLength '... und subtrahieren dies von den remainingBytes
- Else
- currentPacketLength = remainingBytes 'Das wird wohl das letzte Paket sein, zumindest immer dann, wenn es nicht absolut perkekt passt
- remainingBytes = 0
- End If
- Dim sendingBuffer = New Byte(currentPacketLength - 1) {} 'Wir definieren unseren Buffer mit der Größe, die wir weiter oben ja bestimmt haben...
- Await fs.ReadAsync(sendingBuffer, 0, currentPacketLength) '... lesen diese ...
- Await Task.Run(Sub() binaryWriter.Write(sendingBuffer, 0, sendingBuffer.Length)) '... und verschicken diese
- StatusProgressbar.Value = i 'Noch schön dem Benutzer zeigen, was man geschafft hat
- StatusLabel.Text = String.Format("{0} KiB von {1} KiB", (fs.Length - remainingBytes) \ 1024, fs.Length \ 1024)
- Next
- End Using
- End Using
- MessageBox.Show("Die Datei wurde erfolgreich übertragen")
- ResetSending()
- End Sub
- Private Sub ResetSending()
- SendButton.Enabled = True
- PortTextBox.Enabled = True
- IpTextBox.Enabled = True
- SelectPathButton.Enabled = True
- StatusLabel.Text = String.Empty
- StatusProgressbar.Value = 0
- End Sub
Server, Empfangen:
VB.NET-Quellcode
- Imports System.IO
- Imports System.Net
- Imports System.Net.Sockets
- Module Module1
- Const Port As Integer = 10898
- Const BufferSize = 1024
- Sub Main()
- Dim listener = New TcpListener(IPAddress.Any, Port) 'Wir instanziieren und starten den Listener
- listener.Start()
- Console.WriteLine("Der Server wurde gestartet und wartet auf Verbindungen.")
- While True
- Dim client = listener.AcceptTcpClient() 'Wir warten auf eine neue Verbindung
- Try
- Using binaryReader = New BinaryReader(client.GetStream()) 'und holen uns einen BinaryReader, das Gegenstück des BinaryWriters
- Console.WriteLine("Verbindung zu Client hergestellt")
- Dim fileLength = binaryReader.ReadInt32() 'Wir empfangen die Größe der Datei...
- Dim packets = Convert.ToInt32(Math.Ceiling(fileLength / BufferSize)) '... damit wir die Anzahl der zu empfangenen Pakete ausrechnen können
- Console.WriteLine("Datei wird empfangen. Größe: {0} KiB ({1} Pakete)", fileLength \ 1024, packets)
- Dim remainingBytes = fileLength 'Die Anzahl der Bytes, die wir noch empfangen müssen
- Using fs = New FileStream("file.fi", FileMode.Create, FileAccess.Write) 'Wir öffnen erstmal einen neuen FileStream mit Schreibrechten
- For i = 0 To packets - 1
- Dim currentPacketLength As Integer 'Dies ist die Größe des aktuellen Paketes, welches wir empfangen wollen
- If remainingBytes > BufferSize Then 'Wenn noch genug Bytes für ein volles Paket da sind, nehmen wir direkt die Größe...
- currentPacketLength = BufferSize
- remainingBytes -= currentPacketLength '... und subtrahieren dies von den remainingBytes
- Else
- currentPacketLength = remainingBytes 'Das wird wohl das letzte Paket sein, zumindest immer dann, wenn es nicht absolut perkekt passt
- remainingBytes = 0
- End If
- Dim receivingBuffer = binaryReader.ReadBytes(currentPacketLength) 'Wir empfangen die Bytes in der Größe des aktuellen Pakets (currentPacketLength)
- fs.Write(receivingBuffer, 0, receivingBuffer.Length) 'und schreiben dies direkt in den FileStream
- Console.Write("{2}{0} KiB von {1} KiB", (fileLength - remainingBytes) \ 1024, fileLength \ 1024, vbCr)
- Next
- End Using
- End Using
- Console.WriteLine()
- Console.WriteLine("Die Datei wurde erfolgreich übertragen. Die Verbindung wird nun geschlossen")
- Catch ex As Exception
- Console.WriteLine("Ein Fehler ist aufgetreten: {0}", ex.Message)
- End Try
- client.Close()
- End While
- End Sub
- End Module
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VincentTB“ ()