Boardy
Boardy

Reputation: 36237

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.

Upvotes: 1

Views: 12977

Answers (2)

Boardy
Boardy

Reputation: 36237

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;
                        }
                    }
}

Upvotes: 0

ja_mesa
ja_mesa

Reputation: 1969

It's difficult to know where the problem might be (I see your code is OK), but here you have a working example from Microsoft how it should be done, maybe it gives you some clues.

TcpListener server=null;   
try
{
      // Set the TcpListener on port 13000.
      Int32 port = 13000;
      IPAddress localAddr = IPAddress.Parse("127.0.0.1");
      // TcpListener server = new TcpListener(port);
      server = new TcpListener(localAddr, port);

      // Start listening for client requests.
      server.Start();

      // 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;

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

        int i;

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

          // Process the data sent by the client.
          data = data.ToUpper();

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

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

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


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

Upvotes: 2

Related Questions