1

I have an issue with receiving messages in client-server. I have set a default string for testing. It receives the message just fine but it sticks the string together when it sends the second loop. What should i do with this?

Here is the code for sending data(client)

NetworkStream networkStream = tcpclnt.GetStream();
String data = "";
     for (int i = 0; i < 4; i++)
         {
           data = " output here";
           if (networkStream.CanWrite)
              {
                var bytes = Encoding.ASCII.GetBytes(data);
                networkStream.Write(bytes, 0, bytes.Length);
                networkStream.Flush();
              }
          }

And here when it receives the data(server)

private void recieveData()
{
  NetworkStream nStream = tcpClient.GetStream();
  while (!stopReceiving)
      {
         if (nStream.CanRead)
           {
              byte[] buffer = new byte[1024];
              var bytesRead = nStream.Read(buffer, 0, buffer.Length);
              if (bytesRead > 0) recvDt = Encoding.ASCII.GetString(buffer, 0, bytesRead);
              bool f = false;
              f = recvDt.Contains("+@@+");
                    if (f)
                    {
                        string d = "+@@+";
                        recvDt = recvDt.TrimStart(d.ToCharArray());
                        clientDis();
                        stopReceiving = true;
                    }


                    else 
                    {
                        this.Invoke(new rcvData(addHere));
                    }
                }
                Thread.Sleep(1000);
            }

        }


public void addHere() 
        {
            if (recvDt != null && recvDt != "")
            {
                output.Text += "Received Data: " + recvDt;
                recvDt = null;
            }

        }

The output looks like this

Grant Winney
  • 65,241
  • 13
  • 115
  • 165
charlie9495
  • 87
  • 2
  • 17
  • I didn't look through all your code, but `recvDt.Contains("+@@+")` _is_ going to break at some moment. One `Send()` does not equal one `Receive()`, data can be sent and received partially, causing you to receive "+@" in one `Receive()` and "@+" in the next. You need a proper application/framing protocol. – CodeCaster Sep 26 '15 at 10:52
  • i've tried deleteing that part and left the "this.Invoke(new rcvData(addHere));" .. it still has the same result – charlie9495 Sep 26 '15 at 11:10

1 Answers1

2

You are assuming that TCP preserves your messages. It does not. TCP offers a boundaryless stream of bytes. You can receive bytes in any chunk size, including one, but also including all of them at once.

You need to devise an application protocol that allows you to tell messages apart from that stream of bytes. Maybe, prefix the message with its length.

Or, send line-wise and use StreamReader.ReadLine. It handles this for you.

This is a bug:

                    string d = "+@@+";
                    recvDt = recvDt.TrimStart(d.ToCharArray());

You are basically trimming away all chars "+@". Not what you wanted.

Why are you testing CanRead and CanWrite? They are known to be true and even if they were false your program would just ignore the problem and keep going doing nothing. Don't do superstitious checks like that if you can't handle the result anyway.

Probably, you should not use TCP at all. It's hard. Use a higher level technology such as WCF, HTTP, protobuf.

usr
  • 168,620
  • 35
  • 240
  • 369
  • Don't you get tired of posting this reply daily? ;-) I tried writing a [canonical Q&A](http://stackoverflow.com/questions/23713664/why-does-my-client-socket-not-receive-what-my-server-socket-sends) once, but I think it's too convoluted and doesn't really drive the point home that implementing your own protocol properly is _hard_ and unnecessary. – CodeCaster Sep 26 '15 at 11:01
  • 1
    @CodeCaster this is a testament to how bored I am right now :) I guess I should start working now... – usr Sep 26 '15 at 11:02
  • but the message goes through here " this.Invoke(new rcvData(addHere)); " since it did not meet the validation in the if.. and that "+@@+" is receive when the client disconnects – charlie9495 Sep 26 '15 at 11:08
  • Not sure what you mean. f was false resulting in a call to addHere. That prints to the screen. What's surprising about this? Also note, that recvDt might retain its old value. That's another bug. – usr Sep 26 '15 at 11:10
  • ive tried deleting that part and retain the this.Invoke(new rcvData(addHere)); ... it still have the same result – charlie9495 Sep 26 '15 at 11:18
  • Did you understand the part of this answer that tells you about TCP not preserving messages? – usr Sep 26 '15 at 11:24
  • ohh okay.. so how should i fix this sir? – charlie9495 Sep 26 '15 at 11:52
  • `You need to devise an application protocol that allows you to tell messages apart from that stream of bytes. Maybe, prefix the message with its length. Or, send line-wise and use StreamReader.ReadLine. It handles this for you.` Does that help? – usr Sep 26 '15 at 12:00
  • hmmm i understand but i have no idea on how ill do that. Im quite new to c# can you perhaps provide me a line of code sir? please? – charlie9495 Sep 26 '15 at 12:07