Zum Inhalt springen

[C#] Wie schließt man einen Socket richtig


Gateway_man

Empfohlene Beiträge

Hi,

ich habe mir für ein Projekt einen Authentifizierungsserver geschrieben der auch einwandfrei funktioniert.

Bei dem Client jedoch gibt es ein Problem.

Wenn der User einen Logout macht und sich wieder anmelden will, kommt eine Fehlermeldung bei der Zuweisung des Bindings.

Die Meldung sagt in etwa folgendes aus:

Es existiert bereits ein Binding für diesen Port und dieser IP Adresse.

Ich mache nach jeder Verwendung des Clientklasse doch schon folgendes:


            //Client ist vom Typ Socket

            client.Shutdown(SocketShutdown.Both);

            client.Disconnect(true);

            client.Dispose();

Und dennoch wird das Objekt scheinbar nicht richtig geschlossen/freigegeben.

Kennt einer von euch das Problem?

Ich verzweifle allmählich.

lg

Gateway

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi,

ja das ganze ist sehr kurios. Jetzt kommt kein Fehler mehr sondern er bleibt nurnoch bei der Datenabfrage hängen. Eventuell sieht einer von euch den Fehler.

Wenn ich die Klasse mehrfach benutzte hängt er bei der Datenabfrage client.Available > 0.

Ohne Fehler aber es geht einfach nicht weiter. Das ist irgendwie seltsam.

Die Client Klasse (entschuldigt wenn es etwas unsauber ist, aber es ging mir vorerst nur um eine schnelle funktionierende Lösung).


using System;

using System.Collections.Generic;

using System.Text;

using System.Net;

using System.Net.Sockets;

using System.Threading;

using System.IO;


namespace tms_trans.Tms_Authenticate

{


    public class Client : IDisposable

    {

        private Socket client;

        private const int BUFFER_SIZE = 1024;

        private string username = string.Empty;

        private string pass = string.Empty;

        private bool isAuthenticated = false;

        private bool isAsynchronous = false;

        private IPEndPoint localbinding;



                public Client(IPEndPoint Binding)

        {

            client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            client.Bind(Binding) ;

            this.localbinding = Binding;

        }

        public bool Connect(IPEndPoint target)

        {

            bool result = false;

            //try

            //{

                if (client != null)

                {

                    IAsyncResult result1 = client.BeginConnect(target.Address, target.Port, null, null);

                    bool success = result1.AsyncWaitHandle.WaitOne( 5000, true );

                    if (!success)

                    {

                        client.Close();

                        return false;

                    }

                    isAsynchronous = true;

                    ServerMessage msg= GetResponse(2000);

                    if (msg != null && !msg.isMessageEncrypted) {

                        string response = Encoding.ASCII.GetString(msg.ByteMessage);

                        response = response.TrimEnd(new char[] { '\n', '\0', '0', '\r' });

                        Console.WriteLine(response);

                    }

                    result = true;

                }

            //}

            //catch

            //{

            //    result = false;

            //}

            return result;

        }

        public bool Authenticate(string User, string Pass)

        {

            bool result = false;

            SendCommand(Encoding.ASCII.GetBytes("User:" + User));

            ServerMessage msg = GetResponse(2000);

            if (msg != null) {

                string response = Encoding.ASCII.GetString(msg.ByteMessage);

                if (response.StartsWith("+OK"))

                {

                    this.username = User;

                    SendCommand(Encoding.ASCII.GetBytes("Pass:" + Pass));

                    msg = GetResponse(2000);

                    if (msg != null) {

                        response = Encoding.ASCII.GetString(msg.ByteMessage);

                        if (response.StartsWith("+OK"))

                        {

                            this.pass = Pass;


                        }

                        else {

                            result = false;

                            return result;

                        }

                    }

                }

                else {

                    result = false;

                    return result;

                }

            }

            if (username != string.Empty && pass != string.Empty) {

                isAuthenticated = true;

                result = true;

            }

            return result;

        }

        public string RetriveConnectionString()

        {

            string response = string.Empty;

            if (isAuthenticated)

            {

                SendCommand(Encoding.ASCII.GetBytes("RETRCON"));

                ServerMessage msg = GetResponse(2000);

                if (msg != null) {

                    response = Encoding.ASCII.GetString(msg.ByteMessage);

                    response = response.TrimEnd(new char[]{'\n','\0','0','\r'});

                    response = response.Split(new char[] {':' })[1];

                }

            }

            return response;

        }

        public void QUIT()

        {

            SendCommand(Encoding.ASCII.GetBytes("QUIT"));

            //client.BeginDisconnect(true, null, null);

            client.Shutdown(SocketShutdown.Both);

            client.Disconnect(true);

            client.Close();

            client.Dispose();


        }

        private void SendCommand(byte[] Command)

        {

            if (client != null && client.Connected)

            {

                //StreamWriter wr = new StreamWriter(client.GetStream());

                client.Send(Command);

                Thread.Sleep(500);

            }

        }

        private bool WaitForResponse(int timeout)

        {

            bool result = true;

            DateTime start = new DateTime();

            while (client.Available <= 0)

            {

                Thread.Sleep(200);

                if (DateTime.Now.Subtract(start).Milliseconds >= timeout)

                {

                    result = false;

                    break;

                }

            }

            return result;

        }

        private ServerMessage GetResponse(int timeout)

        {

            ServerMessage msg = new ServerMessage();

            if (client != null)

            {

                if (client.Available > 0)

                {

                    string response = string.Empty;

                    while (true)

                    {

                        int hread = 0;

                        byte[] buffer = new byte[BUFFER_SIZE];

                            if (client.Available > 0)

                            hread = client.Receive(buffer, 0, buffer.Length, SocketFlags.None);

                        if (hread <= 0)

                        {

                            break;

                        }

                        else

                        {

                            response += Encoding.ASCII.GetString(buffer).Trim();

                        }

                    }

                    response = response.Trim();

                    response = response.Replace('\n', '\0');

                    bool isNullTerm = true;

                    foreach (char cc in response)

                    {

                        if (cc != '\0')

                        {

                            isNullTerm = false;

                            break;

                        }

                    }

                    response = response.TrimEnd(new char[] {'\n','\0','\r','0' });

                    if (!isNullTerm)

                    {

                        if (response.StartsWith("*"))

                        {

                            msg.isMessageEncrypted = false;

                            byte[] msg1 = Encoding.ASCII.GetBytes(response.ToCharArray(), 1, Encoding.ASCII.GetBytes(response).Length - 1);

                            msg.ByteMessage = msg1;

                        }

                        else if (response.StartsWith("#"))

                        {

                            msg.isMessageEncrypted = true;

                            byte[] msg1 = Encoding.ASCII.GetBytes(response.ToCharArray(), 1, Encoding.ASCII.GetBytes(response).Length - 1);

                            msg.ByteMessage = msg1;

                        }

                        else

                        {

                            msg.isMessageEncrypted = false;

                            msg.ByteMessage = Encoding.ASCII.GetBytes(response);

                        }

                    }

                }

                else

                {

                    if (WaitForResponse(timeout))

                    {

                        string response = string.Empty;

                        while (true)

                        {

                            int hread = 0;

                            byte[] buffer = new byte[BUFFER_SIZE];

                            if (client.Available > 0)

                            hread = client.Receive(buffer, 0, buffer.Length, SocketFlags.None);

                            if (hread <= 0)

                            {

                                break;

                            }

                            else

                            {

                                response += Encoding.ASCII.GetString(buffer).Trim();

                            }

                        }

                        response = response.Trim();

                        response = response.Replace('\n', '\0');

                        bool isNullTerm = true;

                        foreach (char cc in response)

                        {

                            if (cc != '\0')

                            {

                                isNullTerm = false;

                                break;

                            }

                        }

                        if (!isNullTerm)

                        {

                            if (response.StartsWith("*"))

                            {

                                msg.isMessageEncrypted = false;

                                byte[] msg1 = Encoding.ASCII.GetBytes(response.ToCharArray(), 1, Encoding.ASCII.GetBytes(response).Length - 1);

                                msg.ByteMessage = msg1;

                            }

                            else if (response.StartsWith("#"))

                            {

                                msg.isMessageEncrypted = true;

                                byte[] msg1 = Encoding.ASCII.GetBytes(response.ToCharArray(), 1, Encoding.ASCII.GetBytes(response).Length - 1);

                                msg.ByteMessage = msg1;

                            }

                            else

                            {

                                msg.isMessageEncrypted = false;

                                msg.ByteMessage = Encoding.ASCII.GetBytes(response);

                            }

                        }

                    }

                    else { msg = null; }

                }


            }

            return msg;

        }


        private class ServerMessage

        {

            #region Fields

            private bool messageencrypted = false;

            private byte[] bytemessage = null;

            #endregion

            #region constr

            public ServerMessage()

            {


            }

            public ServerMessage(byte[] message, bool ismessageencrypted)

            {

                this.messageencrypted = ismessageencrypted;

                bytemessage = message;

            }

            #endregion

            #region Properties

            public byte[] ByteMessage

            {

                get { return bytemessage; }

                set { bytemessage = value; }

            }

            public bool isMessageEncrypted

            {

                get { return messageencrypted; }

                set { messageencrypted = value; }

            }

            #endregion

        }


        #region IDisposable Member


        public void Dispose()

        {

            if (client != null) {

                if (client.Connected) {

                    client.Shutdown(SocketShutdown.Both);

                    client.Disconnect(true);

                }

                client.Close();

                client.Dispose();

            }

        }


        #endregion

    }




    }




Der Aufruf (ebenfalls etwas unsauber):

            cl = new Client(new IPEndPoint(IPAddress.Any, 3000));

            if (counter >= 2) {

                MessageBox.Show("Sie haben Versucht sich zu oft mit falschen Angaben anzumelden! Das Programm wird jetzt beendet!");

                cl.Dispose();

                Application.ExitThread();

                return;

            }

            if (txt_pass.Text != string.Empty && txt_user.Text != string.Empty) {

                if (cl.Connect(new IPEndPoint(Dns.GetHostAddresses(main.AppSettings.AuthenticHost)[0], main.AppSettings.AuthenticPort)))

                {

                    if (cl.Authenticate(txt_user.Text.Trim(), txt_pass.Text.Trim()))

                    {

                     string con = cl.RetriveConnectionString();

                     if (con != string.Empty) {

                         main.AppSettings.ConnectionString = con;

                     }

                     LogonSuccess = true;

                    }

                    else {

                        counter++;

                        MessageBox.Show("Anmeldedaten wurden vom Server als falsch zurückgewiesen. Bitte prüfen Sie Ihre eingaben!", "Authentifizierungsfehler", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    }

                    cl.QUIT();

                }

                else {

                    MessageBox.Show("Der Server konnte nicht erreicht werden. Folgende Problemlösungen werden empfohlen:" + Environment.NewLine + "1. Prüfen Sie Ihre Internetverbindung" + Environment.NewLine + "2. Prüfen Sie Ihre Firewalleinstellungen (Eventuell fehlt eine Ausnahme für dieses Programm" +

                        Environment.NewLine + "3. Wenn Sie eine langsame Internetverbindung haben ist es möglich das der Timeout zu klein definiert wurde!", "Verbindungsfehler", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    cl.Dispose();

                }

                if (LogonSuccess)

                {

                    this.DialogResult = System.Windows.Forms.DialogResult.OK;

                    this.Close();

                }


            }


Okay irgendwas läuft da nicht rund. Ich glaube ich werde das ganze nochmal sauber neuschreiben.

Aber sofern ihr Anmerkungen habt wäre das klasse xD.

lg

Gateway

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...