Datei versand. Wie versende ich eine Datei zu einem Programm


Fridulin

Erfahrenes Mitglied
Hallo

Ich hoffe einer von euch kann mir Helfen. Es geht darum, ich möchte gerne ein Programm schreiben bzw. 2 Programme. Diese sollen Dateien untereinander Austauschen können. Also mit anderen Worten, mit dem einen Programm "Server" schicke ich eine X - Beliebige Datei zu dem "client" welcher diese Datei daraufhin empfängt. Wie mache ich dies ambesten? Mit Sockets? Beide Programme sollen mal als Server fungieren und mal als Client.
Kann mir einer ein Tipp geben wie ich das am besten / am einfachsten Lösen kann?

Grüße und vielen Dank
 

Fridulin

Erfahrenes Mitglied
Vielen Dank für deine Antwort ich werde mich mal damit richtig auseinandersetzen. Diese sieht sehr vielversprechend aus.

Grüße
 
Zuletzt bearbeitet:

Fridulin

Erfahrenes Mitglied
Ich habe mir jetzt die Klassen zu gemüte geführt und auch einigermaßen verstanden, nur wie sende ich jetzt Daten. Ich finde bei MSDN auch keine TcpServer Klasse.

Grüße und Danke


--- Edit oder brauch man das nicht ---

// Create a TcpClient.
// Note, for this client to work you need to have a TcpServer

Diese aussage verwirrt mich ein wenig. Normalerweise sollte man doch damit ne verbindung aufbauen?
Code:
	stream.Write(data, 0, data.Length);
 
Zuletzt bearbeitet:

Norbert Eder

Erfahrenes Mitglied
TcpListener -> Server
TcpClient -> Client

Stream.Write: Du verwendest einen Stream, in den du Daten schreibst. Der TcpListener oder auch der Client empfangen diesen. Die Daten musst du dann auslesen und entsprechend behandeln.
 

Fridulin

Erfahrenes Mitglied
Achso ist das, Danke.
Ist aber sehr complex das ganze. Vorallem bei MSDN beschrieben....
Eventuell ein gut kommentiertes Beispiel, oder eine andere kleine Hilfestellung wüßtest du nicht zufällig?
Es ist ja auch unschön, wenn man nur ein Server oder nur ein Client Programmiert hat. Dann kann man es ja garnicht Testen.

Grüße
 

Norbert Eder

Erfahrenes Mitglied
TcpListener:

Code:
class MyTcpListener
{
  public static void Main()
  {    
    try
    {
      // Set the TcpListener on port 13000.
      Int32 port = 13000;
      IPAddress localAddr = IPAddress.Parse("127.0.0.1");
      
      // TcpListener server = new TcpListener(port);
      TcpListener server = new TcpListener(localAddr, port);

      // Start listening for client requests.
      server.Start();
         
      // Buffer for reading data
      Byte[] bytes = new Byte[256];
      String data = null;

      // Enter the listening loop.
      while(true) 
      {
        Console.Write("Waiting for a connection... ");
        
        // Perform a blocking call to accept requests.
        // You could also user server.AcceptSocket() here.
        TcpClient client = server.AcceptTcpClient();            
        Console.WriteLine("Connected!");

        data = null;

        // Get a stream object for reading and writing
        NetworkStream stream = client.GetStream();

        int i;

        // Loop to receive all the data sent by the client.
        while((i = stream.Read(bytes, 0, bytes.Length))!=0) 
        {   
          // Translate data bytes to a ASCII string.
          data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
          Console.WriteLine(String.Format("Received: {0}", data));
       
          // Process the data sent by the client.
          data = data.ToUpper();

          byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);

          // Send back a response.
          stream.Write(msg, 0, msg.Length);
          Console.WriteLine(String.Format("Sent: {0}", data));            
        }
         
        // Shutdown and end connection
        client.Close();
      }
    }
    catch(SocketException e)
    {
      Console.WriteLine("SocketException: {0}", e);
    }
      
    Console.WriteLine("\nHit enter to continue...");
    Console.Read();
  }   
}
TcpClient:
Code:
public void Connect(String server, String message) 
{
  try 
  {
    // Create a TcpClient.
    // Note, for this client to work you need to have a TcpServer 
    // connected to the same address as specified by the server, port
    // combination.
    Int32 port = 13000;
    TcpClient client = new TcpClient(server, port);
    
    // Translate the passed message into ASCII and store it as a Byte array.
    Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);         

    // Get a client stream for reading and writing.
   //  Stream stream = client.GetStream();
    
    NetworkStream stream = client.GetStream();

    // Send the message to the connected TcpServer. 
    stream.Write(data, 0, data.Length);

    Console.WriteLine("Sent: {0}", message);         

    // Receive the TcpServer.response.
    
    // Buffer to store the response bytes.
    data = new Byte[256];

    // String to store the response ASCII representation.
    String responseData = String.Empty;

    // Read the first batch of the TcpServer response bytes.
    Int32 bytes = stream.Read(data, 0, data.Length);
    responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
    Console.WriteLine("Received: {0}", responseData);         

    // Close everything.
    client.Close();         
  } 
  catch (ArgumentNullException e) 
  {
    Console.WriteLine("ArgumentNullException: {0}", e);
  } 
  catch (SocketException e) 
  {
    Console.WriteLine("SocketException: {0}", e);
  }
    
  Console.WriteLine("\n Press Enter to continue...");
  Console.Read();
}
 

Fridulin

Erfahrenes Mitglied
Nochmal herzlichen Dank, ich habe sie jetzt beide mit WindowsForms zum laufen gebracht. Ich versuche nun gerade ne Lösung zu finden, wenn die übertragung fertig ist, daß der Listener sich schließt und danach Probiere ich denn mal eine Datei zu senden.

Grüße und Danke nochmals
 

Norbert Eder

Erfahrenes Mitglied
PS: Den Sourcecode den du von mir erhalten hast, ist aus der MSDN. Zu finden direkt beim TcpListener und beim TcpClient ....
 

Fridulin

Erfahrenes Mitglied
Ich hatte den unter anderem dort ehrlich gesagt auch gesehen, wußte nur nichts damit anzufanngen. Dort waren mehrere Bruchstücke von dem Programm. Habe die Suche benutzt und wurde von den Stücken zugeschmißen und ich habe dann nicht mehr durchgesehen.
Aber dank dir wo du es so übersichtlich rauskopiert hast, habe ichs einigermaßen durschaut

Grüße
 

Fridulin

Erfahrenes Mitglied
Ich glaube ich könnte noch einmal deine Hilfe gut grbauchen. Es geht darum eine Datei zu schicken. Gehe ich recht von in der Anahme, daß man sie erstmal auslesen muß, also folgendermaßen:
Code:
int i = 0;
StreamReader lesen = new StreamReader("c:\test.txt", true);
lesen.BaseStream.Seek(0,SeekOrigin.Begin); 
string [] arrZeilen = new string [1000];
while (lesen.Peek() != -1)
{
arrZeilen[i] = lesen.ReadLine();
i++; 
}
Byte[] data2 = System.Text.Encoding.ASCII.GetBytes(arrZeilen[i]);
in soweit Funktioniert es auch nur wenn ich die letzte Zeile Byte[] data2... mit in die While schleife packe, erkennt er sie ja nachher nicht mehr:
Code:
stream.Write(data2, 0, data.Length);
Oder gehe ich das ganze Komplett falsch an, nacher sollen es ja auch keine Textdateien mehr Sein die er schickt, nur so nebnbei erwähnt.
Oder muß ich jeden einzelnen durchganz verschicken? D.h. eine Zeile der Datei Lesen > und dann absenden > Lesen > Absenden?

Grüße und vielen Dank
 
Hi!

Hast du es schonmal mit der BlockCopy-Methode versucht, damit kann man eigentlich ganz elegant viele Arten von Arrays in Byte-Blöcke kopieren. Die Methode gehört zur Buffer-Klasse, vielleicht machst du dich da mal schlau oder probierst es hiermit:
Code:
string [] arrZeilen = new string [1000];

for(...)

Byte[] data2=new byte[Buffer.ByteLength(arrZeilen)];

Buffer.BlockCopy(arrZeilen,0,data2,0,data2.Length);

myStream.Write(data2,0,data2.Length);

Gruß
MC
 

Fridulin

Erfahrenes Mitglied
Hi, Danke für deine Antwort. Habe deine Lösung mal eben ausprobiert. Ich bekomme dann die Fehlermeldung Object must be an array of primitives, weißt du was das bedeutet?

Grüße
 

Fridulin

Erfahrenes Mitglied
Ich habe es mit einer Textdatei geschafft diese zu versenden. Jetzt möchte ich aber gerne ein anderen Typ verschicken, wenn ich dies mit meiner Funktion versuche erscheint folgende Fehlermeldung:
String referenze not set to an instance of a string. Und ich habe keine Ahnung was das Bedeutet.

Hast du oder eventuell noch ein anderer, wie ich ambesten eine x Beliebige Datei einlesen kann? evt. Mit dem ByteReader? Habe ich irgendwo mal gelesen....

Grüße
 

Caracho

Mitglied
Hi,

machs einfach so:
Code:
byte[] buffer = new byte[1024];
int bytesRead;

using(FileStream fs = new FileStream("test.txt", FileMode.Open))
	while( (bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0 )
		stream.Write(buffer, 0, bytesRead);

stream.Flush();
 

Fridulin

Erfahrenes Mitglied
Hi, Danke für die Antwort. Er sendet so nur ganz ganz langsam und auch nur bis 204kb wenn es um eine Zip datei geht. Hast du evt. noch eine Idee?
Grüße.

also mit deinen beispiel sende ich diese und mit folgendes lese ich die Datei wieder aus:
Code:
while((i = stream.Read(bytes, 0, bytes.Length))!=0) 
{ 
StreamWriter sw = new StreamWriter(Application.StartupPath + "\" + "speichern.zip", true);
sw.NewLine = "";
sw.WriteLine(bytes);
sw.Close(); 
....
}
Grüße
 
Hi!

Nur der Vollständigkeit halber, hab grad folgendes gelesen:

Buffer class is applicable to the following primitive types: Boolean, Char, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Single, and Double.

String fällt also leider nicht unter primitive types. Sorry!!

Weiter gutes Gelingen...
 

Alexander Schuc

crazy-weasel
Hi.

Habe den Thread jetzt nur so überflogen, aber du solltest dir bissl mehr Gedanken noch machen!
Einfach wild drauf los die Daten einer Datei zu senden ist nicht so geschickt, was ist wenn die gegenseite die Dateien nicht will? Oder woher soll der Empfänger nun wissen was für eine Datei du ihm schickst? (Dateiname..)

Also solltest du dem Empfänger zuerst ein "Angebot" machen und dann warten was er dazu zu sagen hat. Wenn er die Datei haben will, schick sie ihm, wenn nicht, mach was anderes. Zusätzlich wäre ein Timeout nicht schlecht, nachdem du aufhörst auf das Ok bzw. Nein zu warten.

Code:
S = Sender
E = Empfänger
|          S          |          E          |
|-------------------------------------------|
|   FILE bla.zip      |      *wartet*       |
|      *wartet*       |      OK bla.zip     |
|   *daten senden*    |   *daten empfangen* |

oder

|          S          |          E          |
|-------------------------------------------|
|   FILE bla.zip      |      *wartet*       |
|      *wartet*       |   ERROR bla.zip     |
|      *beenden*      |   *entscheide du*   |
Im Anhang findest nen Beispiel.
Die Dateien jeweils extra zu einer ausführbaren Datei kompilieren. Zuerst den Receiver starten, danach den Sender. Beim Sender wirst ausserdem noch die IPAdresse ändern wollen. Einfach mal den Empfänger starten, steht dann dort auf welche IP er lauscht.
(Wie gesagt, einfaches Beispiel)

Beim Sender kannst dann den Pfad zu einer lokalen Datei angeben, diese wird dann gesendet. Beim Empfänger muss der Transfer "gestartet" werden. Wenn die Aufforderung kommt einfach "n" für "Transfer nicht starten" und "y" für "Transfer starten" eingeben. (Mit Enter bestätigen.)

Viel Spass..
 

Anhänge

Fridulin

Erfahrenes Mitglied
Dankeschön, genau so etwas habe ich als Beispiel gebraucht. Ist schon rellativ einfach gehalten, daß auch ich da halbwegs durchblicken kann.
So etwas hatte ich evt. eh vor mit einer Abfrage ob man die Datei annehmen will, aber habe ein paar schwierigkeiten gehabt einige Probleme zu Lösen. Ich habe es z.B: nur geschafft Textdatei zu senden und zu Empfangen, bei anderen Dateien Funktioniert es komischerweise nicht. Die Datei ist zu klein und er überträgt auch nur ganz langsam. Ich werde gleich mal den Datei Sende rund Empfänger von deinm Programm einbauen, damit habe ich bestimmt mehr Erfolg.

Grüße und Danke nochmals!
 
Zuletzt bearbeitet: