1

I have build a app that can connect to my server. Everything is running smoothly, but I have a problem when the server send message to client simultaneously. Such as when the server sends 2 messages in row. The client just receives the first one. Is there possible to get more than one message in row?

Here is my part of code for client:

TcpClient clientSocket;
public string IPS= "###.###.###.###";
public int SocketS = ####;

public void ConnectingToServer()
{
    clientSocket= new TcpClient();
    clientSocket.Connect(IPS, SocketS);
    if (clientSocket.Connected)
    {
        serverStream = clientSocket.GetStream();
        byte[] outStream = System.Text.Encoding.ASCII.GetBytes();
        serverStream.Write(outStream, 0, outStream.Length);
        serverStream.Flush();
    }
}

// Function for send data to server.
public void SendDataToServer(string StrSend)
{
    if (clientSocket.Connected)
    {
        byte[] outStream = System.Text.Encoding.ASCII.GetBytes(StrSend);
        serverStream.Write(outStream, 0, outStream.Length);
        serverStream.Flush();
    }
}

// Function for receive data from server (I put this in looping).
public void getMessage()
{
    if (clientSocket != null)
    {
        if (clientSocket.Connected)
        {
            if (serverStream.DataAvailable)
            {
                int buffSize = 0;
                buffSize = clientSocket.ReceiveBufferSize;
                byte[] inStream = new byte[buffSize];
                serverStream.Read(inStream, 0, buffSize);
                string StrReceive= System.Text.Encoding.ASCII.GetString(inStream);
            }
        }
    }
}
andre
  • 23
  • 2
  • 7
  • 2
    You should not ignore the return value from `serverStream.Read(inStream, 0, buffSize);`. You may not necessarily get all of the message in one go. Not sure if that is actually causing your problem though. – Daniel Kelley Feb 06 '13 at 09:10
  • @DanielKelley i have checked incoming message from server, and all is right so that should be not the problem. – andre Feb 06 '13 at 09:12
  • possible duplicate of [C# Async Sockets Server Receive Problems](http://stackoverflow.com/questions/5934469/c-sharp-async-sockets-server-receive-problems) – jgauffin Feb 06 '13 at 09:14
  • @andre I strongly urge you to read the documentation on `NetworkStream.Read` - http://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.read.aspx – Daniel Kelley Feb 06 '13 at 09:15
  • DanielKelley is correct. You can not expect everything sent to be received in the same `Read`. That's not how TCP works. Read the answer to the question that I linked to. – jgauffin Feb 06 '13 at 09:15
  • @jgauffin: how is that a dupe? I see no use of async sockets here. In fact, given the size of both questions and the time difference between question and your comment, I can't see how you could even ascertain that it's a dupe. – paxdiablo Feb 06 '13 at 09:17
  • Because you have missunderstood TCP in the same way as the other asker had done. Did you even read the answer? – jgauffin Feb 06 '13 at 09:21
  • i have follow the documentation and not ignore the return value. but the tcp client, still cant get more than 1 message in row. when i try to send message from server every 1 second, it works. the tcp client read all of it. but the problem is i wanna the tcp client can get more then 1 message in row – andre Feb 07 '13 at 07:40

1 Answers1

1

The send/receive functions of socket do not guarantee that all the data you provided will be sent/received at one call. The functions return actual number of sent/received bytes. In your case, you must not ignore the result of the serverStream.Read(...) method call.

That is why application-level protocol should be designed to exchange the things (you call it "messages").

There are many approaches to design the protocol, but let's consider the following "message" protocol as an example:

----------------------------------------------------
| Number of string bytes | String bytes in UTF-8   |
----------------------------------------------------
| 1 byte                 | 2 - ... bytes           |
----------------------------------------------------

Sending the "message": the string should be converted to UTF-8 (for example) representation and sent it with the byte length of the byte representation (as described above).

Receiving the message: receive the data to memory buffer. The process of extracting the "message" is opposite to the sending ones. Of course, you can receive more than one "message" at once, so process the buffer thoroughly.

Example

I have just written a small article with code example.

Community
  • 1
  • 1
  • Why don't you just vote to close when my answer in the other question says just that? – jgauffin Feb 06 '13 at 09:33
  • @jgauffin, yes, I see. Another question contains more generic answer and uses `BinarySerializer` class. I would recommend manual serialization (UTF-8 byte buffer) instead of `BinaryFormatter` class if the application should work **only with text messages** (please see **Size** section here: [BinaryFormatter vs. Manual Serializing](http://www.codeproject.com/Articles/311944/BinaryFormatter-or-Manual-serializing)). – Sergey Vyacheslavovich Brunov Feb 06 '13 at 09:55
  • @andre, I will provide the example soon. – Sergey Vyacheslavovich Brunov Feb 07 '13 at 11:32
  • @SergeyBrunov thank you dude. i already have figured out what the main problem. there was the data i send from server didn't have any message terminator/end line. so when i added the end line character it works perfectly. when i implemented with bufferedstream class that you explain it works very efficient n increase my code performance. – andre Feb 11 '13 at 01:14