Zum Inhalt springen

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


Empfohlene Beiträge

Geschrieben

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

Geschrieben

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

Erstelle ein Benutzerkonto oder melde Dich an, um zu kommentieren

Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können

Benutzerkonto erstellen

Neues Benutzerkonto für unsere Community erstellen. Es ist einfach!

Neues Benutzerkonto erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde Dich hier an.

Jetzt anmelden

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...