1

I've written a little socket application in C# that checks for the current version of my program at every start, now in my test program for this everything works, i can send the string from the server and it will be properly shown on the client, but when I try to use an if statement with that string it just does not work. Example:

    public void rcv(NetworkStream ns, TcpClient clientSocket)
    {
        on = false;
    //sending some random string so the server will respond
       Byte[] sendBytes = Encoding.ASCII.GetBytes("bla");
        ns.Write(sendBytes, 0, sendBytes.Length);
    //receiving server response 
        byte[] bytes = new byte[clientSocket.ReceiveBufferSize];
        int bytesread = clientSocket.ReceiveBufferSize;
        ns.Read(bytes, 0, bytesread);
    //received response, now encoding it to a string from a byte array
        string returndata =Encoding.ASCII.GetString(bytes);
        ver = Convert.ToString(returndata);
        //MessageBox.Show("ver\n" + ver);
        //MessageBox.Show("return\n" + returndata);
        on = true;
        if (ver== "2.0.1")
        {
            MessageBox.Show("iahsd");
        }
    }

So as you can see, the test string im using that is being sent by the server is "2.0.1" does does display properly on a label, a message box and a textbox that i put in for testing. but the if branch at the end of the class does not accept it and skips over it, if i put an else statement in, it skips to that.

i have tried everything me and my friends could think of, tried changing the encoding, sent different strings, etc ..

full code of the client : http://pastebin.com/bQPghvAH

Kai
  • 38,985
  • 14
  • 88
  • 103
  • Should not really be difficult to put a breakpoint on the if and check what is the value in the ver variable – Steve Nov 16 '12 at 13:23
  • It's always interesting to see the way some people think about things. What do *you* think that calling `Convert.ToString(returndata);` will do, when `returndata` is already defined to be a `string`? – Damien_The_Unbeliever Nov 16 '12 at 13:30
  • @Steve the value of ver is the proper string, in this case "2.0.1" but it does not work.. i set the value of ver to a textbox right before the if earlier |||||| Damien_The_Unbeliever honestly i was just trying around the weirdest stuff out of desperation in the end, i know that does not make any sence, but the problem itself didnt make any sense to me either –  Nov 16 '12 at 13:32
  • Try to do a Trim() on the ver value. – Steve Nov 16 '12 at 13:37
  • i tried ver.Trim(); right after i put the value into it, didnt work –  Nov 16 '12 at 13:53
  • Well, what is `ver` then? How about a break point and verifying that ver.Length == 5, and ver.ToCharArray() are the proper characters? – sisve Nov 16 '12 at 15:57

2 Answers2

1

The "2.0.1" compiled in your code is stored as Unicode. http://msdn.microsoft.com/en-us/library/362314fe(v=vs.110).aspx

You are treating the value from the server as ASCII encoded text, and then comparing it to a Unicode string.

Observe:

    static void Main(string[] args)
    {
        string a = "hello";
        byte[] b = UnicodeEncoding.Unicode.GetBytes(a);
        string c = ASCIIEncoding.ASCII.GetString(b);

        Console.WriteLine(a == c);
    }

The solution is to use String.Compare...

Console.WriteLine(String.Compare(a,c)==0);
matt-dot-net
  • 4,204
  • 21
  • 24
  • I would like to be able to use letters aswell with the code, thats why i chose a string, i have tried encoding it to Unicode though, it didnt work either –  Nov 16 '12 at 13:28
  • If you have two variables in code that are both defined to be of type `string`, then they'll both contain Unicode strings. It doesn't matter that one of them originated from a series of bytes and were translated as if those bytes were ASCII. – Damien_The_Unbeliever Nov 16 '12 at 13:34
  • the unicode string `2.0.1` should be identical to ASCII string `2.0.1` – jgauffin Nov 18 '12 at 17:15
  • jgauffin, see the code above. It's not the case that they are the same. You need to look at how the == operator compares two strings. – matt-dot-net Nov 20 '12 at 18:18
  • The answer is to use String.Compare(a,c)==0 – matt-dot-net Nov 20 '12 at 18:19
  • Damien_The_Unbeliever, it does matter. If you have string a="hello" and string b="hello" then the compiler actually gives these two variables the same reference. You can verify by testing (object)a==(object)b; In this case, we are dealing with two references and you have to understand how == works with strings – matt-dot-net Nov 20 '12 at 18:23
1

Stream.Read(...) returns the number of bytes read. You need to use this value to determine where your string ends, by using the Encoding.GetString(Byte[] bytes, Int32 index, Int32 count) overload.

Byte[] buffer = ...;
var bytesRead = stream.Read(buffer, 0, buffer.Length);
var returnedData = Encoding.ASCII.GetString(buffer, 0, bytesRead);
sisve
  • 19,501
  • 3
  • 53
  • 95