none
Mit Socket-Client senden und empfangen RRS feed

  • Frage

  • Hi,

    es geht um die Klient-Programmierung mit Sockets.
    Frage 1:

    Wenn ich ein Socket im Konstruktor erzeuge und in sendMessage() oder receiveMessage() ihn benutze dann funkzioniert dass nur ein mal und beim zweiten Senden kommt es zur Exception "Make sure you have not released a resource before attempting to use it". Das kann man dadurch lösen, dass man am Ende keine socket.Close() macht. Aber so wird meine Verbindung immer geöffnet und ich möchte das nicht. In der Beschreibung zur Close() steht, dass dadurch geöfnete Verbindung geschlossen wird und alle Resources befreit werden. Welche Methode kann ich danach aufrufen damit man mit dem bestehenden Socket eine neue Verbindung aufbauen kann? Ich habe probiert Bind(endPoint). Das hat nix gebracht.

    Muss ich also immer ein neues Socket zu erzeugen, wenn ich ne Verbindung geschlossen habe und ne neue Message senden möchte?
    Etwa so:
    Socket client = new (endPoint.AddressFamily,
    SocketType.Stream, ProtocolType.Tcp);
    //---connect to the server---
    client.Connect(endPoint);

    //---send the data---
    byte[] data = ASCIIEncoding.ASCII.GetBytes(msg);
    client.Send(data);
    client.Close();

    Oder gibt's Möglichkeit ihn doch ein mal zu erzeugen und dann später mehrmals zu benutzen?

    Frage 2:
    Mein Server ist in Java umgesetzt. Wenn ich ihn mit Java-Client teste, dann läuft Senden und Empfangen einbandfrei. Wenn ich C#-Client benutze, dann senden funktioniert, aber wird nichts empfangen. Beim Empfangen sieht das Ablauf so aus. Zuerst sende ich an den Server ein Kommando, dann sendet mir der Server eine Antwort. Mein code fürs Empfangen:

    public string receiveMessage(string command)
    {
    string stringData = null;
    try
    {
    Socket client = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
    //---connect to the server---
    client.Connect(endPoint);

    //---send the command---
    byte[] data = ASCIIEncoding.ASCII.GetBytes(command);
    client.Send(data);

    data = new byte[1024];
    //---receive data ---
    int receivedDataLength = client.Receive(data);
    stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
    client.Close();
    }
    catch (Exception ex)
    {
    throw ex;
    }
    return stringData;
    }

    Was mache ich falsch? Hab ich meine receive-Methode "optimal" umgesetzt? Ich bin nicht mit c#-Richtlinien bzgl. Socket-Programmierung vertraut.


    Ich hab schon gesehen in diesem Forum die Antwort auf die Frage socket.Receive(data) blockiert. Aber mich interesiert nicht wieso blockiert und wie kann man das vermeiden, sondern wieso nix empfängt?

    In Java-Client:

                sendCommand("getThis");
                System.out.println(in.readLine()); //<-- Hier wird empfangen.

    nach dem Senden wird sofort empfangen ohne zu blockieren. Der Server sendet ne Antwort sofort nach dem Empfang des Kommando.

    Vielen Dank im Voraus.

    Mittwoch, 20. Oktober 2010 14:41

Alle Antworten

  • Hallo s

    F1, vereinfacht: ein verbundener TCP-Socket stellt eine 'Session' dar, welche mit Close auch beendet wird.
    Dies ist eigentlich schon socket -Grundlage in jeder Sprache, jedem OS.
    Wenn die Session also bestehen bleiben soll, dann kein Close (bzw Shutdown), sondern du musst die Socket-Instanz 'aufbewahren', was wiederum tiefste C#/.NET-Grundlage wäre.

    F2: bei ASCII-Protokollen ist oft ein CR und oder LF - Zeichen als Abschluss nötig...
       (dein java: readLine deutet auch darauf hin)
    Die Frage ist jetzt, ob in C# dein 'msg' schon CR und/oder LF mit enthält, denn ASCIIEncoding.ASCII.GetBytes macht dies sicher nicht.
    Mittwoch, 20. Oktober 2010 15:07
  • Ich habe gerade bemerkt, dass der Java-Server nur nach socket.Close() eine Meldung kriegt. Also es soll irgendwie so ablaufen:

    -----------------------------------------------------------------------------------------------------------------

    byte[] data = ASCIIEncoding.ASCII.GetBytes(command);
    client.Send(data);

    data = new byte[1024];

    //--- Hier kommt etwas das client.Receive(data) nicht blockiert.


    int receivedDataLength = client.Receive(data);
    stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
    client.Close();

    -----------------------------------------------------------------------------------------------------------------

    Das Kommando wird nach dem client.Close() vom Server empfangen. Kriegt mein Klient danach Daten vom Server? Wenn nicht wie soll ich das umstrukturieren?

    Mittwoch, 20. Oktober 2010 15:20