natli
natli

Reputation: 3822

Really long message cut off on socket receive

I just noticed that my socket client wasn't receiving the same data the server was sending back to it. The text gets cut off after 8192 characters.

Is there some limit I am not aware of? How do I get past this?

The client uses this code:

//Send and Receive
public string sendAndReceiveMSG(string msg)
{
    try
    {
        NetworkStream serverStream = clientSocket.GetStream();
        string sendresponse = sendMSG(msg, serverStream);
        if (sendresponse == "ConnectionCrash")
        {
            return sendresponse;
        }
        else if (sendresponse == "OK")
        {
            string receiveresponse = receiveMSG(serverStream);
            return receiveresponse;
        }
        return "UnknownErrorInternal";
    }
    catch (Exception ex)
    {
        return "UnknownErrorInternal";
    }
}

//Send msg
private string sendMSG(string msg, NetworkStream serverStream)
{
    try
    {
        byte[] outStream = System.Text.Encoding.ASCII.GetBytes(msg);
        serverStream.Write(outStream, 0, outStream.Length);
        serverStream.Flush();
        return "OK";
    }
    catch (Exception ex)
    {
        endSock();
        return "ConnectionCrash";
    }
}

//Receive msg
private string receiveMSG(NetworkStream serverStream)
{
    try
    {
        byte[] inStream = new byte[10025];

        int buffSize = clientSocket.ReceiveBufferSize;
        dynamic bytesRead = serverStream.Read(inStream, 0, buffSize);

        string returndata = System.Text.Encoding.ASCII.GetString(inStream, 0, bytesRead);
        return returndata;
    }
    catch (Exception ex)
    {
        endSock();
        return "ConnectionCrash";
    }
}

The client then gets a response from the server like so;

string recv = client.sendAndReceiveMSG("someRequest");

Upvotes: 1

Views: 2963

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1064304

You have only processed one call to Read. This behaviour is entirely expected; you very rarely get all the data in a single packet (frankly I'm amazed you didn't notice it sooner).

You need to decide on a "framing" policy (i.e. how you distinguish each sub-message - maybe new lines if text based, or length-prefix for binary) - and obtain a frames worth of data before processing. This usually means calling Read in a loop, or (for text) using something like a StreamReader which handles that for you (i.e. calling ReadLine() in a loop).

If there is only one message on the socket, and the caller closes their connection, you can dispense with framing, and just read until Read returns something non-positive (i.e. EOF).

Upvotes: 5

Related Questions