F
FLASHCODER
Guest
I have a client android (Java) that firstly sends to server a string with a delimited prefix "|CONNECTION|" with device information, the server process fine and show the result correctly.
Now i want know how make this same logic with a binary data (a bitmap in my case), i tried make this, but when android sends
dos.writeInt(array.length);
or
dos.write(array, 0, array.length);
i have a error in my switch...case
void server_Received(Listener l, Info i, string received)
{
string[] cmd = received.Split('|');
switch (cmd[1]) {
}
}
that says something like:
index out of range
already when android sends:
dos.writeBytes("|PRINT|");
works fine, similar to when "|CONNECTION|" is received.
Then i want know what the solution to make works this switch...case of server_Received(); routine?
I have saw this question (about android code) and tested, but the result is the same of my following code.
The other possible solution can be create a other Async Socket Server and other Socket on android, only to send/receive this bitmap, but belive that still possible receive in same socket (string and binary data).
Also already was suggested use a ObjectOutputStream (android), on attempt of send all only one time, and not separated (like already was made), so cmd[1] on server probably could be |PRINT|. But i still not tested this approach.
Follow is all relevant code (C# Server and Client Java android):
Form:
namespace MyServer
{
public partial class frmMain : Form
{
Listener server;
Thread startListen;
Bitmap _buffer;
public frmMain()
{
InitializeComponent();
server = new Listener();
}
private void startToolStripMenuItem_Click(object sender, EventArgs e)
{
startListen = new Thread(listen);
startListen.Start();
}
void listen()
{
server.BeginListen(101); // Listen on port 101
server.Received += new Listener.ReceivedEventHandler(server_Received);
server.Disconnected += new Listener.DisconnectedEventHandler(server_Disconnected);
}
void server_Disconnected(Listener l, Info i)
{
Invoke(new _Remove(Remove), i);
}
void server_Received(Listener l, Info i, string received)
{
string[] cmd = received.Split('|');
switch (cmd[1])
{
case "CONNECTION":
Invoke(new _Add(Add), i, cmd[2] + " - " + cmd[3] + " - " + cmd[4]);
break;
case "PRINT":
RecvScreenshot(i);
break;
}
}
delegate void _Add(Info i, string device);
void Add(Info i, string device)
{
string[] splitIP = i.RemoteAddress.Split(':');
ListViewItem item = new ListViewItem();
item.Text = i.ID.ToString();
item.SubItems.Add(splitIP[0]);
item.SubItems.Add(device);
item.Tag = i;
lvConnections.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
.SetValue(lvConnections, true, null);
lvConnections.Items.Add(item);
}
delegate void _Remove(Info i);
void Remove(Info i)
{
foreach (ListViewItem item in lvConnections.Items)
{
if ((Info)item.Tag == i)
{
item.Remove();
break;
}
}
}
private void RecvScreenshot(Info i)
{
var lengthData = new byte[4];
var lengthBytesRead = 0;
while (lengthBytesRead < lengthData.Length)
{
var read = i.sock.Receive(lengthData, lengthBytesRead, lengthData.Length - lengthBytesRead, SocketFlags.None);
if (read == 0) return;
lengthBytesRead += read;
}
Array.Reverse(lengthData);
var length = BitConverter.ToInt32(lengthData, 0);
if (length > 0)
{
var imageData = new byte[length];
var imageBytesRead = 0;
while (imageBytesRead < imageData.Length)
{
var read = i.sock.Receive(imageData, imageBytesRead, imageData.Length - imageBytesRead, SocketFlags.None);
if (read == 0) return;
imageBytesRead += read;
}
using (var stream = new MemoryStream(imageData))
{
var bitmap = new Bitmap(stream);
Invoke(new ImageCompleteDelegate(ImageComplete), new object[] { bitmap });
}
}
}
private delegate void ImageCompleteDelegate(Bitmap bitmap);
private void ImageComplete(Bitmap bitmap)
{
if (_buffer != null)
{
_buffer.Dispose();
}
_buffer = new Bitmap(bitmap);
pictureBox1.Size = _buffer.Size;
pictureBox1.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (_buffer == null) return;
e.Graphics.DrawImage(_buffer, 0, 0);
}
}
}
Listener:
class Listener
{
Socket s;
public List<Info> clients;
public delegate void ReceivedEventHandler(Listener l, Info i, string received);
public event ReceivedEventHandler Received;
public delegate void DisconnectedEventHandler(Listener l, Info i);
public event DisconnectedEventHandler Disconnected;
bool listening = false;
public Listener()
{
clients = new List<Info>();
s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public bool Running
{
get { return listening; }
}
public void BeginListen(int port)
{
s.Bind(new IPEndPoint(IPAddress.Any, port));
s.Listen(100);
s.BeginAccept(new AsyncCallback(AcceptCallback), s);
listening = true;
}
public void StopListen()
{
if (listening == true)
{
s.Close();
listening = false;
}
}
void AcceptCallback(IAsyncResult ar)
{
Socket handler = (Socket)ar.AsyncState;
Socket sock = handler.EndAccept(ar);
Info i = new Info(sock);
clients.Add(i);
Console.WriteLine("New Connection: " + i.ID.ToString());
i.Send("INFO" + Environment.NewLine);
sock.BeginReceive(i.buffer, 0, i.buffer.Length, SocketFlags.None, new AsyncCallback(ReadCallback), i);
handler.BeginAccept(new AsyncCallback(AcceptCallback), handler);
}
void ReadCallback(IAsyncResult ar)
{
Info i = (Info)ar.AsyncState;
try
{
int rec = i.sock.EndReceive(ar);
if (rec != 0)
{
string data = Encoding.ASCII.GetString(i.buffer, 0, rec);
Received(this, i, data);
}
else
{
Disconnected(this, i);
return;
}
i.sock.BeginReceive(i.buffer, 0, i.buffer.Length, SocketFlags.None, new AsyncCallback(ReadCallback), i);
}
catch (Exception ex)
{
Disconnected(this, i);
i.sock.Close();
clients.Remove(i);
}
}
}
Info:
public class Info
{
public Socket sock;
public Guid ID;
public string RemoteAddress;
public byte[] buffer = new byte[8192];
public Info(Socket sock)
{
this.sock = sock;
ID = Guid.NewGuid();
RemoteAddress = sock.RemoteEndPoint.ToString();
}
public void Send(string data)
{
byte[] buffer = Encoding.UTF8.GetBytes(data);
sock.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback((ar) =>
{
sock.EndSend(ar);
}), buffer);
}
}
Android (Java):
while (clientSocket.isConnected()) {
// Sending device information
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(clientSocket.getOutputStream()));
if (line.equalsIgnoreCase("INFO")) {
byte[] data = ("|CONNECTION|" + Build.MANUFACTURER + "|" + Build.MODEL + "|" + Build.VERSION.RELEASE).getBytes(StandardCharsets.UTF_8);
out.writeInt(data.length);
out.write(data, 0, data.length);
out.flush();
}
}
///////////////////////////////////////////////////////////////////////////////
// Sending a bitmap in array
DataOutputStream dos;
try {
dos = new DataOutputStream(clientSocket.getOutputStream());
dos.writeBytes("|PRINT|");
dos.writeInt(array.length);
dos.write(array, 0, array.length);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
Continue reading...
Now i want know how make this same logic with a binary data (a bitmap in my case), i tried make this, but when android sends
dos.writeInt(array.length);
or
dos.write(array, 0, array.length);
i have a error in my switch...case
void server_Received(Listener l, Info i, string received)
{
string[] cmd = received.Split('|');
switch (cmd[1]) {
}
}
that says something like:
index out of range
already when android sends:
dos.writeBytes("|PRINT|");
works fine, similar to when "|CONNECTION|" is received.
Then i want know what the solution to make works this switch...case of server_Received(); routine?
I have saw this question (about android code) and tested, but the result is the same of my following code.
The other possible solution can be create a other Async Socket Server and other Socket on android, only to send/receive this bitmap, but belive that still possible receive in same socket (string and binary data).
Also already was suggested use a ObjectOutputStream (android), on attempt of send all only one time, and not separated (like already was made), so cmd[1] on server probably could be |PRINT|. But i still not tested this approach.
Follow is all relevant code (C# Server and Client Java android):
Form:
namespace MyServer
{
public partial class frmMain : Form
{
Listener server;
Thread startListen;
Bitmap _buffer;
public frmMain()
{
InitializeComponent();
server = new Listener();
}
private void startToolStripMenuItem_Click(object sender, EventArgs e)
{
startListen = new Thread(listen);
startListen.Start();
}
void listen()
{
server.BeginListen(101); // Listen on port 101
server.Received += new Listener.ReceivedEventHandler(server_Received);
server.Disconnected += new Listener.DisconnectedEventHandler(server_Disconnected);
}
void server_Disconnected(Listener l, Info i)
{
Invoke(new _Remove(Remove), i);
}
void server_Received(Listener l, Info i, string received)
{
string[] cmd = received.Split('|');
switch (cmd[1])
{
case "CONNECTION":
Invoke(new _Add(Add), i, cmd[2] + " - " + cmd[3] + " - " + cmd[4]);
break;
case "PRINT":
RecvScreenshot(i);
break;
}
}
delegate void _Add(Info i, string device);
void Add(Info i, string device)
{
string[] splitIP = i.RemoteAddress.Split(':');
ListViewItem item = new ListViewItem();
item.Text = i.ID.ToString();
item.SubItems.Add(splitIP[0]);
item.SubItems.Add(device);
item.Tag = i;
lvConnections.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
.SetValue(lvConnections, true, null);
lvConnections.Items.Add(item);
}
delegate void _Remove(Info i);
void Remove(Info i)
{
foreach (ListViewItem item in lvConnections.Items)
{
if ((Info)item.Tag == i)
{
item.Remove();
break;
}
}
}
private void RecvScreenshot(Info i)
{
var lengthData = new byte[4];
var lengthBytesRead = 0;
while (lengthBytesRead < lengthData.Length)
{
var read = i.sock.Receive(lengthData, lengthBytesRead, lengthData.Length - lengthBytesRead, SocketFlags.None);
if (read == 0) return;
lengthBytesRead += read;
}
Array.Reverse(lengthData);
var length = BitConverter.ToInt32(lengthData, 0);
if (length > 0)
{
var imageData = new byte[length];
var imageBytesRead = 0;
while (imageBytesRead < imageData.Length)
{
var read = i.sock.Receive(imageData, imageBytesRead, imageData.Length - imageBytesRead, SocketFlags.None);
if (read == 0) return;
imageBytesRead += read;
}
using (var stream = new MemoryStream(imageData))
{
var bitmap = new Bitmap(stream);
Invoke(new ImageCompleteDelegate(ImageComplete), new object[] { bitmap });
}
}
}
private delegate void ImageCompleteDelegate(Bitmap bitmap);
private void ImageComplete(Bitmap bitmap)
{
if (_buffer != null)
{
_buffer.Dispose();
}
_buffer = new Bitmap(bitmap);
pictureBox1.Size = _buffer.Size;
pictureBox1.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (_buffer == null) return;
e.Graphics.DrawImage(_buffer, 0, 0);
}
}
}
Listener:
class Listener
{
Socket s;
public List<Info> clients;
public delegate void ReceivedEventHandler(Listener l, Info i, string received);
public event ReceivedEventHandler Received;
public delegate void DisconnectedEventHandler(Listener l, Info i);
public event DisconnectedEventHandler Disconnected;
bool listening = false;
public Listener()
{
clients = new List<Info>();
s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public bool Running
{
get { return listening; }
}
public void BeginListen(int port)
{
s.Bind(new IPEndPoint(IPAddress.Any, port));
s.Listen(100);
s.BeginAccept(new AsyncCallback(AcceptCallback), s);
listening = true;
}
public void StopListen()
{
if (listening == true)
{
s.Close();
listening = false;
}
}
void AcceptCallback(IAsyncResult ar)
{
Socket handler = (Socket)ar.AsyncState;
Socket sock = handler.EndAccept(ar);
Info i = new Info(sock);
clients.Add(i);
Console.WriteLine("New Connection: " + i.ID.ToString());
i.Send("INFO" + Environment.NewLine);
sock.BeginReceive(i.buffer, 0, i.buffer.Length, SocketFlags.None, new AsyncCallback(ReadCallback), i);
handler.BeginAccept(new AsyncCallback(AcceptCallback), handler);
}
void ReadCallback(IAsyncResult ar)
{
Info i = (Info)ar.AsyncState;
try
{
int rec = i.sock.EndReceive(ar);
if (rec != 0)
{
string data = Encoding.ASCII.GetString(i.buffer, 0, rec);
Received(this, i, data);
}
else
{
Disconnected(this, i);
return;
}
i.sock.BeginReceive(i.buffer, 0, i.buffer.Length, SocketFlags.None, new AsyncCallback(ReadCallback), i);
}
catch (Exception ex)
{
Disconnected(this, i);
i.sock.Close();
clients.Remove(i);
}
}
}
Info:
public class Info
{
public Socket sock;
public Guid ID;
public string RemoteAddress;
public byte[] buffer = new byte[8192];
public Info(Socket sock)
{
this.sock = sock;
ID = Guid.NewGuid();
RemoteAddress = sock.RemoteEndPoint.ToString();
}
public void Send(string data)
{
byte[] buffer = Encoding.UTF8.GetBytes(data);
sock.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback((ar) =>
{
sock.EndSend(ar);
}), buffer);
}
}
Android (Java):
while (clientSocket.isConnected()) {
// Sending device information
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(clientSocket.getOutputStream()));
if (line.equalsIgnoreCase("INFO")) {
byte[] data = ("|CONNECTION|" + Build.MANUFACTURER + "|" + Build.MODEL + "|" + Build.VERSION.RELEASE).getBytes(StandardCharsets.UTF_8);
out.writeInt(data.length);
out.write(data, 0, data.length);
out.flush();
}
}
///////////////////////////////////////////////////////////////////////////////
// Sending a bitmap in array
DataOutputStream dos;
try {
dos = new DataOutputStream(clientSocket.getOutputStream());
dos.writeBytes("|PRINT|");
dos.writeInt(array.length);
dos.write(array, 0, array.length);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
Continue reading...