Reputation: 65
I've succesfully made the connection using TCP Sockets from C# to Java (Android). I can send and receive string messages no problem. However when I try to receive a PNG image sent from C# Server, I get only black screen on Android Activity View.
Basically, the Server listens and waits until client sends a message. When the server receives the message, it will respond with sending an image to client.
C# Server:
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received. Now let's send an image.
byte[] pic = new byte[5000*1024];
pic = ImageConverter.imageToByteArray(System.Drawing.Image.FromFile("C:\\ic_launcher.png"));
clientStream.Write(pic, 0, pic.Length);
clientStream.Flush();
}
Android client:
Socket s = new Socket("192.168.1.154", 8888);
DataInputStream ins = new DataInputStream(s.getInputStream());
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//Let's send output message
String outMsg = "TCP connecting to " + 8888 + System.getProperty("line.separator");
out.write(outMsg);
out.flush();
//Receive the image from server.
int bytesRead;
byte[] pic = new byte[5000*1024];
bytesRead = ins.read(pic, 0, pic.length);
//Decode the byte array to bitmap and set it on Android ImageView
Bitmap bitmapimage = BitmapFactory.decodeByteArray(pic, 0, bytesRead);
ImageView image = (ImageView) findViewById(R.id.test_image);
image.setImageBitmap(bitmapimage);
//Show in android TextView how much data in bytes has been received (for debugging)
String received;
received= Integer.toString(bytesRead);
test.setText(received);
//close connection
s.close();
Now received variable shows that ~3000 bytes have been transfered, while the image size is actually 4.147 bytes (shown in Windows Explorer), well that doesn't sound right.
So anyway why the image does not show up in Android Activity? What am I missing here?
Upvotes: 0
Views: 4334
Reputation: 101192
First of all. TCP do not send messages, it sends byte streams. A byte stream that you Receive()
can contain anything from a small part of a message to several messages. Do not assume that you'll receive exactly one message with one Receive()
.
You would have noticed that if you had proper error handling in your server. Don't just ignore exceptions or disconnections. Handle them.
The easiest way to solve your problem is to send a integer header which tells the length. Read that header and then continue call Read
until the entire image have been transferred.
The reason to why your string worked is that the message is tiny and that you didn't transfer anything else directly after. Thus giving you the illusion of sending a message. (Try to send two messages directly after each other, Nagle algorithm should pack them together so that you'll receive them in the same Read()
).
Upvotes: 1
Reputation: 2796
you can successfully do this by converting the image object to base64String, and then converting the base64String again to image at C# server.
Here is the same thing I have achieved using the .NET webservices and for Iphone platform.
Upvotes: 0