0

I obtained the following code from MSDN :

using System;       
using System.IO;      
using System.Net;
using System.Net.Sockets;
using System.Text;

class MyTcpListener
{
public static void Main()
{
    TcpListener server = null;
    try
    {

        Int32 port = 13000; // Set the TcpListener on port 13000.
        IPAddress localAddr = IPAddress.Parse("127.0.0.1");


        server = new TcpListener(localAddr, port); // TcpListener server = new TcpListener(port);
        server.Start(); // Start listening for client requests.

        // Buffer for reading data
        Byte[] bytes = new Byte[256];
        String data = null;

        // Enter the listening loop.
        while (true)
        {
            Console.Write("Waiting for a connection... ");

            // Perform a blocking call to accept requests.
            // You could also user server.AcceptSocket() here.
            TcpClient client = server.AcceptTcpClient();
            Console.WriteLine("Connected!");

            data = null;
            NetworkStream stream = client.GetStream();// Get a stream object for reading and writing

            int i;


            while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)  // Loop to receive all the data sent by the client.
            {     
               data = System.Text.Encoding.ASCII.GetString(bytes, 0, i); // Translate data bytes to a ASCII string.
                Console.WriteLine("Received: {0}", data);        
                data = data.ToUpper();// Process the data sent by the client.

                byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);

                stream.Write(msg, 0, msg.Length); // Send back a response.
                Console.WriteLine("Sent: {0}", data);


                if(data == "STOP")
                {
                    Console.WriteLine("Stop command Received.");
                    Console.ReadKey();
                    Environment.Exit(0);
                }


                Console.WriteLine(data.Length);

            }
            client.Close(); // Shutdown and end connection
        }
    }
    catch (SocketException e)
    {
        Console.WriteLine("SocketException: {0}", e);
    }
    finally
    {
        server.Stop();// Stop listening for new clients.
    }

    Console.WriteLine("\nHit enter to continue...");
    Console.Read();
}
}

except the following lines which were inserted by me:

            if(data == "STOP")
            {
                Console.WriteLine("Stop command Received.");
                Console.ReadKey();
                Environment.Exit(0);
            }

I sent a string "STOP" via a tcp client. However, in the server, comparing the received string "STOP" against "STOP" in the 'if block' was of no use ie., nothing in that block got executed.

What is the actual error in this approach ? What changes should I make to compare the strings properly ?

  • You really need to [learn how to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/), you should be able to step through the code with the debugger to the `if(data == "STOP")` line and see what is causing the problem. – Scott Chamberlain Mar 14 '17 at 17:05

2 Answers2

3

If Ben's answer does not solve your problem there is a 2nd major problem with your code.

Your code has no guarantees that you won't get ST in one read and OP in the next read. A single send is allowed to be split in to multiple reads, and multiple sends are allowed to be combined in to a single read. So sending Test then STOP could show up as TestSTOP when you call the read function.

You need to add additional logic to the code to tell when one message stops and another starts on the receiving side. This is called Message Framing and for your additions to the program to work you will need to add that logic in to your program.

Community
  • 1
  • 1
Scott Chamberlain
  • 116,967
  • 28
  • 260
  • 389
2

If you are sending the text via WriteLine (vs. Write), the string you are getting won't be "STOP" but rather "STOP\r\n", so you would want to Trim() the string to check for equality.

data.Trim() == "STOP" 
Ben Abraham
  • 482
  • 4
  • 10
  • Just to know, why does the received string get added with \r\n. Is there purpose. –  Mar 14 '17 at 17:10
  • 2
    Otherwise, how would the other end know that they've received the whole thing? – David Schwartz Mar 14 '17 at 17:12
  • @programminghorse that is the message framing I talked about in my answer. You would read till you see a \r\n then once you hit one of those you start doing your processsing to see if the message is what you expect. – Scott Chamberlain Mar 14 '17 at 17:56
  • The code that is sending is what is appending the \r\n on the end of the message being sent (likely using WriteLine function). This is both good and bad depending on what you want to do. Like @Scott has mentioned, there is no 100% guarantee that what you send will be received in the same sequence (eg. "Test" then "STOP" could be recieved as "TestSTOP" depending on lots of external factors [although, you will most likely see it come over as expected when testing]). So the \r\n can be helpful for you splitting messages (assuming the messages themselves don't have \r\n in them) – Ben Abraham Mar 14 '17 at 18:41
  • @ BenAbraham , Sometimes, when I send back the data received at the server back to the client, I get the data which were sent earlier by the client and not the immediate one. Is that a symptom of the problem you have mentioned earlier. –  Mar 17 '17 at 17:10