Search code examples
c#androidsocketstcp

Reading data from a TCP Socket not getting all of the data


I am working on a C# and android client/server application.

Android is sending a message to C# and I can see it is sending the correct data, however C# doesn't receive all of it.

Below is the code I have in C#

TcpListener tcpListener = new TcpListener(IPAddress.Any, serverTCPPort);
                tcpListener.Start();

                while (true)
                {
                    tcpClient = tcpListener.AcceptTcpClient();

                    stream = tcpClient.GetStream();
                    reader = new StreamReader(stream);
                    writer = new StreamWriter(stream);
                    writer.NewLine = "\r\n";
                    writer.AutoFlush = true;
                    byte[] serverData = new byte[tcpClient.ReceiveBufferSize];
                    int length = stream.Read(serverData, 0, serverData.Length);
                    string received = Encoding.ASCII.GetString(serverData, 0, length);
}

Below is how I am sending the data via Android

i

f (contactInformation.photoBase64String != null) {
                bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), Uri.parse(contactInformation.photoBase64String));

                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
                byte[] b = baos.toByteArray();
                bitmap64Encoded = Base64.encodeToString(b, Base64.DEFAULT);
            }

            Toast.makeText(context, "Incoming call from " + contactInformation.contactName, Toast.LENGTH_LONG).show();

            XmlSettings xmlSettings = new XmlSettings();
            xmlSettings.setIndent(true);
            XmlWriter xmlWriter = new XmlWriter(xmlSettings);

            xmlWriter.writeStartDocument();
            xmlWriter.writeStartElement("StatusManager");
            xmlWriter.writeElementString("Command", Defines.ServerCommands.IncomingCall.toString());
            xmlWriter.writeStartElement("CallInformation");
            xmlWriter.writeElementString("PhoneNumber", phoneNumber);
            xmlWriter.writeElementString("ContactName", contactInformation.contactName);
            if (contactInformation.photoBase64String != null)
            {
                xmlWriter.writeElementString("PhotoUri", bitmap64Encoded);
            }
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();

            String xml = xmlWriter.returnXmlOutput();

            TCPSender tcpSender = new TCPSender(context, DeviceManagement.servers.get(0), xmlWriter.returnXmlOutput());
            Thread thread = new Thread(tcpSender);
            thread.start();

The TCP Sender is

@Override
    public void run() {
        Log.d("TCPSender", xml);
        HelperClass helperClass = new HelperClass();
        try
        {
            Socket socket = new Socket(foundServerInformation.ipAddress, foundServerInformation.tcpServerPort);
            
            OutputStream out = socket.getOutputStream();
            PrintWriter output = new PrintWriter(out);
            output.println(xml);
            output.flush();

I guess the data is too big for the byte array but I can't find a way of how to ensure I get all of the information that Android is sending.


Solution

  • I've finally managed to get it working, it was something to do with using the SendReceiveBuffer which I did try but didn't work but now it does so I guess I missed something.

    Below is the code I am using to receive all of the data

    TcpListener tcpListener = new TcpListener(IPAddress.Any, serverTCPPort);
                    tcpListener.Start();
                    string received = "";
                    while (true)
                    {
                        tcpClient = tcpListener.AcceptTcpClient();
    
                        stream = tcpClient.GetStream();
                        reader = new StreamReader(stream);
                        writer = new StreamWriter(stream);
                        writer.NewLine = "\r\n";
                        writer.AutoFlush = true;
                        byte[] bytes = new byte[tcpClient.SendBufferSize];
                        int recv = 0;
                        while (true)
                        {
                            recv = stream.Read(bytes, 0, tcpClient.SendBufferSize);
                            received += System.Text.Encoding.ASCII.GetString(bytes, 0, recv);
    
                            if (received.EndsWith("\n\n"))
                            {
                                break;
                            }
                        }
    }