I have write a program that consists server and client. The server makes a screenshot desktop, and the client receives the screenshot and shows on the form. There is a problem in the data transfer, I see only a small strip. I checked before sending the image on the server is ok. However, the client receives the wrong image. What is wrong?
XAML:
<Window x:Class="TestTCP.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TestTCP" Height="350" Width="525">
<Grid>
<Image x:Name="img1" Margin="0"/>
</Grid>
</Window>
Code C#:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Task rec = new Task(WaitClientQuery);
rec.Start();
Task tk = new Task(Send);
tk.Start();
}
private void Send()//server part. take screen and send image
{
Bitmap temp = CaptureScreen(true);
MemoryStream ms3 = new MemoryStream();
BitmapImage image = new BitmapImage();
byte[] img_byte;
try
{
((System.Drawing.Bitmap)temp).Save(ms3, System.Drawing.Imaging.ImageFormat.Bmp);
image.BeginInit();
ms3.Seek(0, SeekOrigin.Begin);
image.StreamSource = ms3;
image.EndInit();
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
img_byte = ms.ToArray();
}
try
{
TcpClient client = new TcpClient("192.168.1.64", 4444);
NetworkStream netstream = client.GetStream();
netstream.Write(img_byte, 0, img_byte.Length);
netstream.Close();
client.Close();
}
catch (Exception)
{
}
}
catch (Exception ee)
{
}
}
[StructLayout(LayoutKind.Sequential)]
struct CURSORINFO
{
public Int32 cbSize;
public Int32 flags;
public IntPtr hCursor;
public POINTAPI ptScreenPos;
}
[StructLayout(LayoutKind.Sequential)]
struct POINTAPI
{
public int x;
public int y;
}
[DllImport("user32.dll")]
static extern bool GetCursorInfo(out CURSORINFO pci);
[DllImport("user32.dll")]
static extern bool DrawIcon(IntPtr hDC, int X, int Y, IntPtr hIcon);
const Int32 CURSOR_SHOWING = 0x00000001;
public static Bitmap CaptureScreen(bool CaptureMouse)
{
Bitmap result = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
try
{
using (Graphics g = Graphics.FromImage(result))
{
g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
if (CaptureMouse)
{
CURSORINFO pci;
pci.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(CURSORINFO));
if (GetCursorInfo(out pci))
{
if (pci.flags == CURSOR_SHOWING)
{
DrawIcon(g.GetHdc(), pci.ptScreenPos.x, pci.ptScreenPos.y, pci.hCursor);
g.ReleaseHdc();
}
}
}
}
}
catch
{
result = null;
}
return result;
}
void WaitClientQuery()//receive data(client)
{
try
{
IPAddress ip ;
IPAddress.TryParse("192.168.1.64", out ip);
TcpListener listener = new TcpListener(ip, 4444);
listener.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();
Thread thread = new Thread(new ParameterizedThreadStart(ReadMessage));
thread.IsBackground = true;
thread.Start(client);
}
}
catch (Exception ex)
{
}
}
void ReadMessage(object obj)
{
try
{
TcpClient client = (TcpClient)obj;
NetworkStream netstream = client.GetStream();
byte[] arr = new byte[client.ReceiveBufferSize ];
int len = netstream.Read(arr, 0, client.ReceiveBufferSize);
if (len > 0)
{
try
{
Action act = delegate
{
MemoryStream strmImg = new MemoryStream(arr);
BitmapImage myBitmapImage = new BitmapImage();
myBitmapImage.BeginInit();
myBitmapImage.StreamSource = strmImg;
myBitmapImage.EndInit();
img1.Source = myBitmapImage;
};
this.Dispatcher.BeginInvoke(act);
}
catch (Exception ex)
{
string message = ex.Message;
}
}
netstream.Close();
client.Close();
}
catch (Exception ex)
{
}
}
}
P.S. Result, screen program after compile:
click to view
The main root cause the client.ReceiveBufferSize using default value are 8192 byte so the client will not receive enough image which has been transferred from server. In my code, I would like to see at client receive correctly the size of image so I use BinaryWriter to transfer length of image. From client side I have used BinaryReader to read exactly number of bytes and size of image to save bandwidth. Hope this help
At the Send method:
TcpClient client = new TcpClient("192.168.1.64", 4444);
using (NetworkStream netstream = client.GetStream())
{
using (BinaryWriter bw = new BinaryWriter(netstream))
{
bw.Write(img_byte.Length);
bw.Write(img_byte, 0, img_byte.Length);
}
client.Close();
}
At the ReadMessage(object obj)
private void ReadMessage(object obj)
{
try
{
byte[] arr = null;
TcpClient client = (TcpClient) obj;
using (NetworkStream netstream = client.GetStream())
{
using (BinaryReader br = new BinaryReader(netstream))
{
var arrLen = new byte[4];
br.Read(arrLen, 0, 4);
int len = BitConverter.ToInt32(arrLen, 0);
if (len > 0)
{
arr = new byte[len];
int read = 0;
while (read != len)
{
read += br.Read(arr, read, arr.Length - read);
}
}
}
}
if (arr != null && arr.Length > 0)
{
try
{
Action act = delegate
{
MemoryStream strmImg = new MemoryStream(arr);
BitmapImage myBitmapImage = new BitmapImage();
myBitmapImage.BeginInit();
myBitmapImage.StreamSource = strmImg;
myBitmapImage.EndInit();
img1.Source = myBitmapImage;
};
this.Dispatcher.BeginInvoke(act);
}
catch (Exception ex)
{
string message = ex.Message;
}
}
client.Close();
}
catch (Exception ex)
{
}
}
I expect client.ReceiveBufferSize on client side has wrong information
I would recomend to read data in loop.
if(netstream.CanRead)
{
byte[] myReadBuffer = new byte[1024];
int numberOfBytesRead = 0;
do
{
numberOfBytesRead = netstream.Read(myReadBuffer, 0, myReadBuffer.Length);
}
while(netstream.DataAvailable);
}
and save data into the List or memorystream
Or may be easier way, before your server send all data, send the size
netstream.Write(img_byte.Length); //does not work with NetworkStream
netstream.Write(img_byte, 0, img_byte.Length);
and client can read it first to allocate appropriate buffer.
To send and receive particular data type I would recomend
build BinaryWriter from your NetworkStream
using (BinaryWriter writer = new BinaryWriter(netstream))
Related
I am trying to get the printScreen from another device using socket.
My sending device (windowsce 6.0) code is
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Data;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace ServerComputer
{
class Program
{
static Socket sendsocket;
enum RasterOperation : uint { SRC_COPY = 0x00CC0020 }
[DllImport("coredll.dll")]
static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, RasterOperation rasterOperation);
[DllImport("coredll.dll")]
private static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("coredll.dll")]
private static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);
public static void Main(string[] args)
{
Console.Out.WriteLine("Gildo Lindo Fon");
try
{
sendsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//The instantiation of socket, IP for 192.168.1.106, 10001 for Port
IPEndPoint ipendpiont = new IPEndPoint(IPAddress.Parse("192.168.0.24"), 81);
sendsocket.Connect(ipendpiont);
//Establishment of end point
Console.Out.WriteLine("starting thread");
Thread th = new Thread(sendImageThread);
//th.IsBackground = true;
th.Start();
}
catch (Exception ee)
{
Console.Out.WriteLine(ee.Message);
return;
}
}
private static Bitmap GetScreen()
{
Rectangle bounds = Screen.PrimaryScreen.Bounds;
IntPtr hdc = GetDC(IntPtr.Zero);
Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format16bppRgb565);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
IntPtr dstHdc = graphics.GetHdc();
BitBlt(dstHdc, 0, 0, bounds.Width, bounds.Height, hdc, 0, 0,RasterOperation.SRC_COPY);
graphics.ReleaseHdc(dstHdc);
}
ReleaseDC(IntPtr.Zero, hdc);
return bitmap;
}
private static void sendImageThread()
{
Console.Out.WriteLine("SENDING");
while (true)
{
try
{
MemoryStream ms = new MemoryStream();
Bitmap bitmapScreen = GetScreen();
bitmapScreen.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); //Here I use the BMP format
bitmapScreen.Save(".\\printimg.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] b = ms.ToArray();
sendsocket.Send(b);
ms.Close();
}
catch (Exception ee)
{
Console.Out.WriteLine(ee.Message);
break;
}
Thread.Sleep(1000);
}
}
}
}
My receiver code is like this:
using System.Net;
using System.Net.Sockets;
namespace httpScreenClient;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Socket hostSocket = null!;
Thread thread = null!;
string localIP = string.Empty;
string computrHostName = string.Empty;
int dataSize = 0;
byte[] imageBytes = new byte[800 * 650 * 16*10]; //Picture of great 16 bpp RGB 565
private void mainForm_Load(object sender, EventArgs e)
{
computrHostName = Dns.GetHostName();
IPHostEntry hostname = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in hostname.AddressList)
{
if (ip.AddressFamily.ToString() == "InterNetwork")
{
localIP = ip.ToString();
}
}
this.Text = this.Text + " | " + localIP;
}
private void liveScreen_Click(object sender, EventArgs e)
{
connectSocket();
}
private void connectSocket()
{
Socket receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint hostIpEndPoint = new IPEndPoint(IPAddress.Parse("192.168.0.24"), 81);
//Connection node
receiveSocket.Bind(hostIpEndPoint);
receiveSocket.Listen(10);
//MessageBox.Show("start");
hostSocket = receiveSocket.Accept();
thread = new Thread(new ThreadStart(trreadimage))
{
IsBackground = true
};
thread.Start();
}
private void trreadimage()
{
while (true) {
string imageName = "stremScreen.JPG";
try
{
dataSize = hostSocket.Receive(imageBytes);
if (dataSize > 0)
{
MemoryStream ms = new MemoryStream(imageBytes);
Image img = Image.FromStream(ms);
img.Save(imageName, System.Drawing.Imaging.ImageFormat.Jpeg);
videoBox.Image = img;
ms.Close();
}
}
catch (Exception ee)
{
//messagebox.show("foi aqui - " + ee.message);
break;
}
Thread.Sleep(1500);
}
trreadimage();
}
}
I checked the screenprinted saved on the sending side and is alright, but what I getting on the receiver side is very messy, as there was some wrongs crops one over the other...
Streamed image received:
Do you guys have any suggest about what could be going on? actually I was getting the Image.FromStream() error too (https://social.msdn.microsoft.com/Forums/en-US/820fe38b-3fb6-4490-9608-10c4133e4a50/imagefromstreamms-parameter-is-not-valid?forum=aspdotnetwebpages) on the receiver side, that's why I left the catch {} part of the code empty... I didn't get to solve this error.
After some tries I got the solution by compressing the byte array before sending with
private static byte[] Compress(byte[] data)
{
MemoryStream output = new MemoryStream();
using (DeflateStream dstream = new DeflateStream(output, CompressionMode.Compress))
{
dstream.Write(data, 0, data.Length);
}
return output.ToArray();
}
And decompressing it on the other side with:
private static byte[] Decompress(byte[] data)
{
MemoryStream input = new MemoryStream(data);
MemoryStream output = new MemoryStream();
using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress))
{
dstream.CopyTo(output);
}
return output.ToArray();
}
I´ve got a problem with my TCP client.
My TCP server sends a Bitmap as a String to the TCP client. At the moment there are 15 bmp per second. My Problem is, that most of them are read as "//////...." when I convert the received byte array to a string.
My TCP server code is (C#):
private void StreamWriter(byte[] writeMessage)
{
TcpClient client = new TcpClient();
client.Connect(IPAddress.Parse(Ip), Port);
NetworkStream streamSender = client.GetStream();
streamSender.Write(writeMessage, 0, writeMessage.Length);
streamSender.Flush();
streamSender.Close();
client.Close();
}
private void sendImage()
{
while (send)
{
MemoryStream mem = new MemoryStream();
image.Save(mem, System.Drawing.Imaging.ImageFormat.Bmp);
mem.Close();
mem.Dispose();
StreamWriter(Encoding.ASCII.GetBytes(Convert.ToBase64String(mem.ToArray())));
i++;
}
}
My client code is (Android Studio):
class MyServerThread implements Runnable {
#Override
public void run() {
try {
ServerSocket ss = new ServerSocket(50000);
while (true) {
Socket s = ss.accept();
InputStream is = (s.getInputStream());
BufferedInputStream bufferedReader = new BufferedInputStream(is);
byte[] contents = new byte[440000];
int bytesRead = 0;
while ((bytesRead = bufferedReader.read(contents)) != -1) {
message = new String(contents, 0, bytesRead);
}
is.close();
bufferedReader.close();
if (message.equals("Connection OK!")) {
createIP();
} else {
createPic();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I found a solution.
This is the client code now:
class MyServerThread implements Runnable {
#Override
public void run() {
try {
ServerSocket ss = new ServerSocket(50000);
while (true) {
Socket s = ss.accept();
InputStream is = (s.getInputStream());
BufferedReader r = new BufferedReader(new InputStreamReader(is));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line);
}
message = total.toString();
s.close();
is.close();
if (message.equals("Connection OK!")) {
createIP();
} else {
createPic();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I have this client and server code.
Client:
namespace ClientTest
{
internal class Program
{
private static TcpClient client;
private static NetworkStream stream;
private static void Main(string[] args)
{
string temp;
client = new TcpClient("192.168.1.2",5052);
stream = client.GetStream();
Console.WriteLine(client.SendBufferSize);
while ((temp = Console.ReadLine()) != "exit")
{
Send(temp);
}
Thread one=new Thread(()=> SendFile(new FileInfo(#"1.doc")));
one.Start();
Thread two=new Thread(()=> SendFile(new FileInfo(#"2.docx")));
two.Start();
// Console.ReadKey(true);
}
public static void SendFile(FileInfo file)
{
stream = client.GetStream();
byte[] id = BitConverter.GetBytes((ushort)1);
byte[] size = BitConverter.GetBytes(file.Length);
byte[] fileName = Encoding.UTF8.GetBytes(file.Name);
byte[] fileNameLength = BitConverter.GetBytes((ushort)fileName.Length);
byte[] fileInfo = new byte[12 + fileName.Length];
id.CopyTo(fileInfo, 0);
size.CopyTo(fileInfo, 2);
fileNameLength.CopyTo(fileInfo, 10);
fileName.CopyTo(fileInfo, 12);
stream.Write(fileInfo, 0, fileInfo.Length); //Размер файла, имя
byte[] buffer = new byte[1024 * 32];
int count;
long sended = 0;
using (FileStream fileStream = new FileStream(file.FullName, FileMode.Open))
while ((count = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, count);
sended += count;
Console.WriteLine("{0} bytes sended.", sended);
}
stream.Flush();
}
private static void Send(string message)
{
byte[] id = BitConverter.GetBytes((ushort)0);
byte[] msg = Encoding.UTF8.GetBytes(message);
byte[] msgLength = BitConverter.GetBytes((ushort)msg.Length);
byte[] fileInfo = new byte[12 + msg.Length];
id.CopyTo(fileInfo, 0);
msgLength.CopyTo(fileInfo, 10);
msg.CopyTo(fileInfo, 12);
stream.Write(fileInfo, 0, fileInfo.Length);
stream.Flush();
}
}
}
Server:
namespace Server_Test
{
class Server
{
static void Main(string[] args)
{
Server serv = new Server();
}
private TcpListener listener { get; set; }
private NetworkStream stream { get; set; }
public Server()
{
listener = new TcpListener(IPAddress.Parse("192.168.1.2"), 5052);
listener.Start();
new Thread(ListenForClients).Start();
}
private void ListenForClients()
{
while (true)
{
TcpClient client = this.listener.AcceptTcpClient();
new Thread(HandleClient).Start(client);
}
}
private void HandleClient(object tcpClient)
{
TcpClient client = (TcpClient)tcpClient;
while (client.Connected)
{
Recieve(client);
}
}
private void Recieve(TcpClient client)
{
byte[] buffer = new byte[client.ReceiveBufferSize];
try
{
stream = client.GetStream();
int bytesRead = stream.Read(buffer, 0, 12);
if (bytesRead == 0) return;
ushort id = BitConverter.ToUInt16(buffer, 0);
long len = BitConverter.ToInt64(buffer, 2);
ushort nameLen = BitConverter.ToUInt16(buffer, 10);
stream.Read(buffer, 0, nameLen);
string fileName = Encoding.UTF8.GetString(buffer, 0, nameLen);
if (id == 1)
{
using (BinaryWriter writer = new BinaryWriter(new FileStream(fileName, FileMode.Create)))
{
int recieved = 0;
while (recieved < len)
{
bytesRead = stream.Read(buffer, 0, client.ReceiveBufferSize);
recieved += bytesRead;
writer.Write(buffer, 0, bytesRead);
Console.WriteLine("{0} bytes recieved.", recieved);
}
}
Console.WriteLine("File length: {0}", len);
Console.WriteLine("File Name: {0}", fileName);
Console.WriteLine("Recieved!");
}
else
{
Console.WriteLine(fileName);
}
}
catch (Exception ex)
{
stream.Close();
client.Close();
Console.WriteLine(ex);
}
finally
{
stream.Flush();
}
}
}
}
The problem:i can't send 2 files in threads. If i send 1 file, server receives it and correctly saves.
What changes needed in this code to let client transfer 2 or more files and to let server receive it?
UDP. Added modified SendFile, but in doesn't work.
public static void SendFile(FileInfo file)
{
TcpClient client;
NetworkStream stream;
client = new TcpClient("192.168.1.2", 5052);
stream = client.GetStream();
byte[] id = BitConverter.GetBytes((ushort)1);
byte[] size = BitConverter.GetBytes(file.Length);
byte[] fileName = Encoding.UTF8.GetBytes(file.Name);
byte[] fileNameLength = BitConverter.GetBytes((ushort)fileName.Length);
byte[] fileInfo = new byte[12 + fileName.Length];
id.CopyTo(fileInfo, 0);
size.CopyTo(fileInfo, 2);
fileNameLength.CopyTo(fileInfo, 10);
fileName.CopyTo(fileInfo, 12);
stream.Write(fileInfo, 0, fileInfo.Length); //Размер файла, имя
byte[] buffer = new byte[1024 * 32];
int count;
long sended = 0;
using (FileStream fileStream = new FileStream(file.FullName, FileMode.Open))
while ((count = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, count);
sended += count;
Console.WriteLine("{0} bytes sended.", sended);
}
}
On the client side, your two separate sending threads cannot share the same instance of client = new TcpClient("192.168.1.2",5052); to simultaneously send data. Each thread should have its own instance. Note, however, that it is fine for 2 client sockets to hit the same server-side IP:port simultaneously. It is just that the outbound port on the client-side has to be different between the 2 connections. When you create an additional outbound TCP connection on the client, the TcpClient will automatically use the next available outbound port.
For example, you could try something like the following:
internal class Program
{
private static void Main(string[] args)
{
SenderThreadClass stc1 = SenderThreadClass("192.168.1.2", 5052);
SenderThreadClass stc2 = SenderThreadClass("192.168.1.2", 5052);
Thread one = new Thread(()=> stc1.SendFile(new FileInfo(#"1.doc")));
one.Start();
Thread two = new Thread(()=> stc2.SendFile(new FileInfo(#"2.docx")));
two.Start();
}
}
public class SenderThreadClass
{
private TcpClient client;
private NetworkStream stream;
public SenderThreadClass(string serverIP, int serverPort)
{
client = new TcpClient(serverIP, serverPort);
stream = client.GetStream();
}
public void SendFile(FileInfo file)
{
byte[] id = BitConverter.GetBytes((ushort)1);
byte[] size = BitConverter.GetBytes(file.Length);
byte[] fileName = Encoding.UTF8.GetBytes(file.Name);
byte[] fileNameLength = BitConverter.GetBytes((ushort)fileName.Length);
byte[] fileInfo = new byte[12 + fileName.Length];
id.CopyTo(fileInfo, 0);
size.CopyTo(fileInfo, 2);
fileNameLength.CopyTo(fileInfo, 10);
fileName.CopyTo(fileInfo, 12);
stream.Write(fileInfo, 0, fileInfo.Length); //Размер файла, имя
byte[] buffer = new byte[1024 * 32];
int count;
long sended = 0;
using (FileStream fileStream = new FileStream(file.FullName, FileMode.Open))
while ((count = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, count);
sended += count;
Console.WriteLine("{0} bytes sended.", sended);
}
stream.Flush();
}
}
I want my server to keep listening the the same client. It listen the client only one time. How can i keep reading the data sent from client side.
sk = new Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp);
sk.Bind(new IPEndPoint(IPAddress.Any, 5000));
sk.Listen(-1);
while (true)
{
try
{
Socket client = sk.Accept();
NetworkStream ns = new NetworkStream(client);
byte[] buffer = new byte[32768];
using (MemoryStream ms = new MemoryStream())
{
while (true)
{
int read = ns.Read(buffer, 0, buffer.Length);
if (read <= 0)
break;
ms.Write(buffer, 0, read);
}
}
MemoryStream msi = new MemoryStream(buffer);
Image returnImage = Image.FromStream(msi);
}
catch (Exception)
{
}
}
Finally i found a way to this problem
private void Form1_Load(object sender, EventArgs e)
{
serverSocket = new TcpListener(9361);
clientSocket = default(TcpClient);
Thread listen = new Thread(listenClients);
listen.Start();
}
//this will keep listening the clients
public void listenClients()
{
int counter = 0;
serverSocket.Start();
counter = 0;
while ((true))
{
counter += 1;
clientSocket = serverSocket.AcceptTcpClient();
Thread thread = new Thread(
() => readClient(clientSocket));
thread.Start();
}
}
public void broadcast(Image bmp)
{
pictureBox1.Image = bmp;
} //en
//keep reading the client data
private void readClient(TcpClient inClientSocket)
{
byte[] bytesFrom = new byte[65536];
string dataFromClient = null;
while ((true))
{
try
{
NetworkStream networkStream = inClientSocket.GetStream();
networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
MemoryStream ms = new MemoryStream(bytesFrom);
Image returnImage = Image.FromStream(ms);
broadcast(returnImage);
}
catch (Exception ex)
{
}
} //end while
} //end readClint
c# code
private MemoryStream Read() {
NetworkStream clientStream = _client.GetStream();
MemoryStream messageStream = new MemoryStream();
var inbuffer = new byte[65535];
if(clientStream.CanRead) {
do {
int bytesRead = clientStream.Read(inbuffer,0,inbuffer.Length);
messageStream.Write(inbuffer, 0, bytesRead);
messageStream.Flush();
Debug.Print(messageStream.Length + " added " + bytesRead);
} while(clientStream.DataAvailable); // GOES BEYOND HERE, EVEN THOUGH THERE'S MORE DATA
}
messageStream.Position = 0;
return messageStream;
}
android code
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK){
if(requestCode == ATTACH_FILE_REQUEST){
writeToSocket("<FILE>generic.jpeg");
InputStream input = null;
String filePath = data.getData().getPath().toString();
try {
input = getContentResolver().openInputStream(data.getData());
BufferedInputStream bufferedInputStream = new BufferedInputStream(input);
byte[] bytes = new byte[65535];
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
while((bufferedInputStream.read(bytes)) != -1){
byteArray.write(bytes, 0, bytes.length);
}
socketNetworkHelper.writeFile(byteArray.toByteArray());
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
Toast.makeText(this, "Error in file selection", Toast.LENGTH_LONG).show();
} catch (IOException e2){
e2.printStackTrace();
Toast.makeText(this, "Input/Output Error", Toast.LENGTH_LONG).show();
}
}
}
}
In SocketNetworkHelper.java which has a socket connected:
public void writeFile(byte[] buffer) {
try {
socket.getOutputStream().write(buffer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The question is: How can I get the whole file?
You could also send the filesize as a parameter
private MemoryStream Read(int filesize) {
NetworkStream clientStream = _client.GetStream();
MemoryStream messageStream = new MemoryStream();
var inbuffer = new byte[filesize];
if (clientStream.CanRead) {
int totalBytesRead = 0;
do {
int bytesRead = clientStream.Read(inbuffer, 0, inbuffer.Length);
totalBytesRead += bytesRead;
messageStream.Write(inbuffer, 0, bytesRead);
messageStream.Flush();
} while (totalBytesRead < filesize);
}
messageStream.Position = 0;
return messageStream;