Hallo,
Ich versuche Dateien über TCP zu versenden. Alles klappt perfekt wenn ich es auf dem lokalen Computer mit der IP 127.0.0.1 versuche. Doch wenn ich es über WAN, also außerhalb meines Netzwerkes auf einen anderen Computer hin versuche, dann treten bei Dateien > 5KB große Datenverluste auf ( < 5KB klappt perfekt). Ich weiß nicht, woran das liegt, aber vielleicht kann mir hier ja jemand helfen...
Hier noch der Code zum Senden:
int BufferSize = 1024;
byte[] SendingBuffer = new byte[BufferSize];
progressBox pForm = new progressBox();
pForm.label1.Text = "Sending file to " + remotePCname + "...";
TcpListener tcpFileListener = new TcpListener(IPAddress.Any, 2729);
tcpFileListener.Start();
TcpClient fileClient = tcpFileListener.AcceptTcpClient();
FileStream fileStream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read);
NetworkStream netstream = fileClient.GetStream();
int totalLength = (int)fileStream.Length;
pForm.progressBar1.Maximum = totalLength;
int totalSent = 0;
pForm.Show();
while (totalSent < totalLength)
{
totalSent += fileStream.Read(SendingBuffer, 0, BufferSize);
netstream.Write(SendingBuffer, 0, SendingBuffer.Length);
if (pForm.progressBar1.Value >= pForm.progressBar1.Maximum)
{
pForm.progressBar1.Value = pForm.progressBar1.Minimum;
}
pForm.progressBar1.Value = totalSent;
}
netstream.Close();
tcpFileListener.Stop();
fileClient.Close();
fileStream.Close();
pForm.Close();
und zum Empfangen:
TcpListener tcpFileListener = new TcpListener(IPAddress.Any, 2729);
tcpFileListener.Start();
TcpClient fileClient = tcpFileListener.AcceptTcpClient();
NetworkStream fileStream = fileClient.GetStream();
FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
progressBox pForm = new progressBox();
pForm.label1.Text = "Receiving file from " + remotePCname + "...";
pForm.progressBar1.Maximum = size;
pForm.Show();
byte[] currentRead = new byte[1024];
int bytesRead;
int totalRead = 0;
while (totalRead < size)
{
bytesRead = 0;
try
{
bytesRead = fileStream.Read(currentRead, 0, 1024);
fs.Write(currentRead, 0, currentRead.Length);
if (pForm.progressBar1.Value >= pForm.progressBar1.Maximum)
{
pForm.progressBar1.Value = pForm.progressBar1.Minimum;
}
pForm.progressBar1.PerformStep();
}
catch
{
break;
}
if (bytesRead == 0)
{ break; }
}
tcpFileListener.Stop();
fileStream.Close();
fileClient.Close();
fs.Close();
pForm.Close();
Gruß,
Chester
An dem Punkt, das der ganze Code eher suboptimal ist setze ich jetzt nicht an.
Woher kennt die Empfangsseite die "size"?
Es gibt die Available-Eigenschaft beim TcpClient, die dir angibt ob Daten zu lesen da sind und wann keine mehr da sind.
Zu deinem eigentlichen Fehler jedoch vermute ich, das eine Exception geworfen wird, die du durch dein break unterdrückst. -> Das Break beendet das Empfangen.
Wissen ist nicht alles. Man muss es auch anwenden können.
PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |
Ich sehe direkt zwei Probleme:*TCP ist ein "hoefliches" Protokoll - d.h. der Sender darf sich nicht verabschieden, bevor die Kommunikation mit dem Empfaenger beendet ist. *Beim Senden wird kein Flush aufgerufen - erst nach dem Flush wird 100 % etwas verschickt.
Hallo Chester,
ein weiterer Fehler ist bei
bytesRead = fileStream.Read(currentRead, 0, 1024);
fs.Write(currentRead, 0, currentRead.Length);
Du darfst nur soviel schreiben, wie du auch gelesen hast, also
fs.Write(currentRead, 0, bytesRead);
(Length gibt immer die statische Größe des (Byte-)Arrays zurück.)
PS: Der selbe Fehler ist auch bei der Senden-Methode...
PPS: Packe deinen Code in using-Blöcke anstatt manuell Close() aufzurufen.
@Th69
Scheint ein beliebter Fehler zu sein 😃
Den hatten wir erst kürzlich schon mal hier: NetworkStream in Datei speichern + Fortschrittsanzeige des Downloads
Gruss
Programmierhans
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Vielen Dank für all die Hilfe von eurer Seite!
Es lag vermutlich wirklich daran, dass ich nicht die bytesRead beim Stream verwendet habe, und daran, dass das Flush() nach dem Schreiben in den Stream gefehlt hat.
Nun funktioniert alles wie gewollt. 🙂
Gruß,
Chester
Wo soll ich den using-Block herum packen? Und wie soll der aussehen?
Hallo Chester,
jetzt gehts klar Richtung "Grundlagen". Bitte beachte [Hinweis] Wie poste ich richtig? Punkt 1.1 und 1.1.1.
Weeks of programming can save you hours of planning