Gateway_man Geschrieben 1. August 2011 Geschrieben 1. August 2011 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 Zitieren
Guybrush Threepwood Geschrieben 1. August 2011 Geschrieben 1. August 2011 socket.Close(); Die Meldung sagt in etwa folgendes aus: Es existiert bereits ein Binding für diesen Port und dieser IP Adresse. Die genaue Meldung wäre hilfreich. Schließt der Server die Verbindung auch richtig? Zitieren
Gateway_man Geschrieben 1. August 2011 Autor Geschrieben 1. August 2011 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 Zitieren
Empfohlene Beiträge
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.