Sporadisches Problem mit StreamReader

jokakilla

Grünschnabel
Hallo!
Ich habe vor kurzem mit C# angefangen. Ich programmiere gerade einen kleinen Chat mit Userauthentifizierung. Auf meinem Webspace läuft eine MySQL Datenbank. Man kann sich per Webformular registrieren. Leider komm ich nur von Localhost an die Datenbank ran. Mein Chatserver braucht aber zugriff auf die Userdaten um die Anmeldung zuzulassen oder nicht. Also habe ich ein PHP Skript geschrieben, dass per Get den gefragten Usernamen und den Hash des Passwortes bekommt und eine 1 ausgibt falls der User mit dem Passwort in der Datenbank ist und 0 falls nicht.
Das Problem ist, dass ab und zu eine AccessViolationException beim sResp = oStream.ReadToEnd(); in der folgenden Methode auftritt:

Code:
        public bool userInDatabaseAndPasswordCorrect(string user, byte[] password)
        {
            String OneTimeHashString = "";
            for (int i = 0; i < password.Length; i++)
                OneTimeHashString += password[i].ToString("X2");
            OneTimeHashString = OneTimeHashString.ToLower();
            string sURL = "http://www.meineSeite.de/jokaChat/query.php?accesscode=einHashCodeUmFremdzugriffeZuErschweren&nickname=" + user + "&password=" + OneTimeHashString;
            string sResp = "";
            try
            {
                HttpWebRequest oWebReq = (HttpWebRequest)WebRequest.Create(sURL);

                HttpWebResponse oWebResp = (HttpWebResponse)oWebReq.GetResponse();
                StreamReader oStream = new StreamReader(oWebResp.GetResponseStream(), System.Text.Encoding.UTF8);
                sResp = oStream.ReadToEnd();
                oWebResp.Close();
                oStream.Close();
                if (sResp.Equals("1"))
                    return true; //OK
                else
                    return false; //Anmeldung ablehnen

            }
            catch (System.AccessViolationException ave)
            {
                Console.WriteLine(ave.Source);
                return false; //Anmeldung ablehnen
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false; //Anmeldung ablehnen
            }

Code:
<?php      
        if(strcmp($accesscode, "meinHashcode zur Absicherung") == 0)
        {
          $db_server = "localhost";
          $db_name = "**************";
          $db_user = "***********";
          $db_password = "*********";

          //Verbinden und Datenbank wählen
          $db = @mysql_connect($db_server, $db_user, $db_password) or die("Fehler beim Verbindungsaufbau!");
          mysql_select_db("********", $db) or die("Fehler beim Auswählen der Datenbank!");			
          
          $sql = "SELECT nickname, password FROM `chatUser` WHERE nickname='".$nickname."' and password='".$password."';";

          $result = mysql_query($sql) or die("Fehler bei der Abfrage!");
          
          if(mysql_num_rows($result) > 0)
            echo "1";
          else
            echo "0";
          mysql_close($db) or die("Fehler beim Schließen der Verbindung!");
        }
        else
        {
          echo "0";
        }
?>


Wäre echt super wenn mir da jemand weiter helfen könnte! Mir gehen die Ideen aus!

Edit: Achja noch eine kleine Frage: Gibt es einen Unterschied zwischen string und String?
 
Zuletzt bearbeitet:

Norbert Eder

Erfahrenes Mitglied
Wenn dieses Problem auftritt: Schon einmal die InnerException angesehen? Eventuell stehen darin brauchbare Informationen.

string vs String: string ist nur ein Alias für String. Ergo kein Unterschied.
 

jokakilla

Grünschnabel
Wenn dieses Problem auftritt: Schon einmal die InnerException angesehen? Eventuell stehen darin brauchbare Informationen.

string vs String: string ist nur ein Alias für String. Ergo kein Unterschied.

Danke für die Aufklärung bezüglich String und string!

Hab die Exception schon raus bekommen. Hab mit Wireshark mal den Seitenaufruf gesnifft.
Wenn die DB Abfrage erfolgreich war liefert das Skript zwar 1 aber in Wireshark sieht man was noch so mit kommt. 1 1 0. Die 0 ist wohl zum terminieren. Die erste 1 kein Plan. Auf jeden Fall kommt wenn die Rückgabe 0 ist 2 0 0. Scheinbar interpretiert das ReadToEnd das erste Zeichen als Längenangabe und er versucht zwei Zeichen zu lesen obwohl nur eins kommt. Ich hab das ReadToEnd jetzt durch ein Read ersetzt das IMMER nur ein Zeichen liest.
Außerdem hab ich noch einen Fehler gemacht. Ich hab die Socket Option TCP_Nodelay eingeschaltet also Nagle aus und der Client sendet Benutzernamen (20 Zeichen) und Passwort (64 Zeichen) in zwei Befehlen. Auf der Serverseite lese ich das mit einem Stream.Read(buffer, 0, 84) ein. Manchmal kam das Passwort nicht mehr mit in den buffer rein. Dann war mein Passwort ein String nur aus Nullen. Hab jetzt beim Client einen Sendepuffer in den ich byte Arrays vom Benutzer und Passwort mit copyTo rein kopiere. Somit wird alles in einem gesendet.

Ganz nebenbei gefragt: Wie schwierig ist es den Zugriff auf die PHP Datei SSL zu verschlüsseln? Reicht es wenn mein Webserver das unterstützt und ich statt http https schreibe? Gibt es eine Möglichkeit aus C# raus htaccess Logins auszufüllen?
 
Zuletzt bearbeitet:

Norbert Eder

Erfahrenes Mitglied
Du brauchst am Server ein SSL-Zertifikat. Der Client muss dieses ebenfalls im Zertifikatsspeicher gespeichert haben, oder man wählt hierfür einen Umweg (WebRequest und SSL Zertifikate).

Ein Schutz per .htaccess entspricht einer Basic Authentication, die durch Mitgabe von Credentials bewältigt werden kann.