Image streaming from Java to C# - c#

Java (client side)
relevant code
// Create the encoder and decoder for targetEncoding
Charset charset = Charset.forName("UTF-8");
CharsetDecoder decoder = charset.newDecoder();
CharsetEncoder encoder = charset.newEncoder();
byte[] underlyingBuffer = new byte[100000];
ByteBuffer buffer = ByteBuffer.wrap(underlyingBuffer);
System.out.println("first buffer remaining" + buffer.remaining() + " "
+ buffer.limit());
buffer.order(ByteOrder.LITTLE_ENDIAN);
try {
Socket client = new Socket("localhost", 8080);
OutputStream oStream = client.getOutputStream();
InputStream iStream = client.getInputStream();
//String secondFilePath = "C:\\Users\\pedge\\Desktop\\readData.csv";//this is csv file
//long secondFileLength = ReadFileToCharArray(buffer,secondFilePath , encoder);
String inputImage = "C:\\Users\\pedge\\Desktop\\Desert.jpeg";// image to transfer
ReadFileToCharArray(buffer,inputImage , encoder);
//imageWrite(oStream, inputImage);
buffer.flip();
int dataToSend = buffer.remaining();
int remaining = dataToSend;
while (remaining > 0) {
oStream.write(buffer.get());
--remaining;
}
public static long ReadFileToCharArray(ByteBuffer buffer, String filePath,
CharsetEncoder encoder) throws IOException {
fileCount++;
System.out.println("second buffer remaining" + buffer.remaining() + " "
+ buffer.limit());
StringBuilder fileData = new StringBuilder(100);
File file = new File(filePath);
System.out.println("Size of file ["+fileCount+"] sent is ["+file.length()+"]");
BufferedReader reader = new BufferedReader(new FileReader(filePath));
char[] buf = new char[10000000];
int numRead = 0;
while ((numRead = reader.read(buf)) != -1) {
System.out.println(numRead);
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
buf = new char[1000000];
}
reader.close();
CharBuffer charBuffer = CharBuffer.wrap(fileData.toString()
.toCharArray());
System.out.println("char buffer " + charBuffer.remaining());
ByteBuffer nbBuffer = null;
try {
nbBuffer = encoder.encode(charBuffer);
} catch (CharacterCodingException e) {
throw new ArithmeticException();
}
buffer.putInt(nbBuffer.limit());
System.out.println("buffer information" + buffer.position() + " "
+ buffer.limit() + " nbBuffer information" + nbBuffer.position()
+ " " + nbBuffer.limit());
buffer.put(nbBuffer);
return file.length();
}
C# (Server Side)
static void Main(string[] args)
{
try
{
Run(args);
}
catch (Exception e)
{
Console.Error.WriteLine(e);
}
}
static void Run(string[] args)
{
TcpListener listener = new TcpListener(8080);
listener.Start();
while (true)
{
using (TcpClient client = listener.AcceptTcpClient())
{
try
{
Read(client);
}
catch (Exception e)
{
Console.Error.WriteLine(e);
}
}
}
}
static void Read(TcpClient client)
{
String csvFile4Parsing = "C:\\Users\\pedge\\Desktop\\newReadData.csv";// csv file created from byte stream
Console.WriteLine("Got connection: {0}", DateTime.Now);
NetworkStream ns = client.GetStream();
BinaryReader reader = new BinaryReader(ns);
int length = reader.ReadInt32();
Console.WriteLine("Length of csv is [" + length + "]");
byte[] fileArray = reader.ReadBytes(length);
File.WriteAllBytes(csvFile4Parsing, fileArray);//bytes from stream, written to csv`
Now i am able to transfer the image from java to C# and a file is then created by c#(works perfect)
But when i try to send the image(same as like CSV), it doesn't work at all and even the bytes received at the server end are different from that of client end. I have spent hours now on this with no success. :/
and help will be much appreciated. thanks.

CSV data is text and might require the CharsetEncoder you are using to process the stream before sending it to the C#, but image data is binary and you only want to send a bit-for-bit copy of the data. The problem is likely to be that the stream encoder mistakenly interprets some binary sequences in the image data as text characters that need to be encoded and mangles them.
Just use plain binary stream read and write on both sides (you are already doing it in C#) and confirm that the data is exactly the same. If it isn't, post a hex sample of how it is different.

Finally the solved this issue.
Java(Client)
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class ImageServer {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost", 8000);
//code to send image
File file = new File("C:\\Users\\ashish\\Desktop\\image.jpg");
FileInputStream fileInputStream = new FileInputStream(file);
int count=0;
byte[] fileBytes = new byte[(int)file.length()];
int content;
OutputStream outputStream = socket.getOutputStream();
while((content = fileInputStream.read(fileBytes)) != -1){
outputStream.write(fileBytes, 0, (int)file.length());
}
System.out.println("file size is "+ fileBytes.length);
for(byte a : fileBytes){System.out.println(a);}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
C#(Server)
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
namespace Test.SendImageClient
{
public class Program
{
static void Main(string[] args)
{
TcpListener tcpListener = null;
try
{
IPAddress ipadress = IPAddress.Parse("127.0.0.1");
tcpListener = new TcpListener(ipadress, 8000);
/* Start Listeneting at the specified port */
tcpListener.Start();
byte[] bytes = new byte[6790];
byte[] finalBytes;
while(true){
TcpClient client = tcpListener.AcceptTcpClient();
Console.WriteLine("Connected!");
NetworkStream stream = client.GetStream();
int i;
do
{
i = stream.Read(bytes, 0, bytes.Length);
finalBytes = new byte[i];
Console.WriteLine("Size dynamically is "+i);
for (int n = 0; n < i; n++ )
{
finalBytes[n] = bytes[n];
}
}while(stream.DataAvailable);
File.WriteAllBytes("C:\\Users\\ashish\\Desktop\\newImage.jpg", finalBytes);
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
// Stop listening for new clients.
tcpListener.Stop();
}
}
}
}

Related

Receiving Data only from one machine instead of all machine over TCP/IP

Our Client have a dialysis machine which use Ethernet TCP/IP Protocol and data transfer protocol is XML.It automatically connects to the our computer system by using the configured IP address and port number and sends unsolicited data messages every 60 seconds to our system. Client send data as XML Data Stream. Now I need to store data in XML file.
Below is my code.
Here now problem is, Client is sending data messages from four machines, However my code is capturing data from only one machine, Kindly suggest what I am missing here.
namespace NiproMI
{
class NiproListener
{
public static void GetXMLStream()
{
TcpListener server = null;
try
{
Int32 port = Int32.Parse(AppConfigValues.GetAppConfigValue("Port"));
IPAddress localAddr = IPAddress.Parse(AppConfigValues.GetAppConfigValue("IPAddress"));
server = new TcpListener(localAddr, port);
server.Start();
Byte[] bytes = new Byte[256];
String data = null;
while (true)
{
TcpClient client = server.AcceptTcpClient();
NetworkStream stream = client.GetStream();
string fileName = "NiproMI_" + DateTime.Now.ToString("dd-MM-yyyy--HH-mm-ss-ffff") + ".xml";
int i;
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
WriteToFile(data, fileName);
if (data.Contains("</Rec>"))
{
MoveInputFile(fileName);
fileName = "NiproMI_" + DateTime.Now.ToString("dd-MM-yyyy--HH-mm-ss-ffff") + ".xml";
}
}
}
}
catch (SocketException e)
{
MIEventLogs.WriteLog("SocketException: {0}" + e);
}
finally
{
server.Stop();
}
}
public static void WriteToFile(string sMessage, string fileName)
{
try {
DirectoryInfo logdirFile = new DirectoryInfo(System.Configuration.ConfigurationManager.AppSettings["XmlFilePath"].ToString());
string filePath = logdirFile.FullName;
if (File.Exists(Path.Combine(filePath, fileName)))
{
StreamWriter sw = null;
//Open File
FileStream fs = File.Open(Path.Combine(filePath, fileName), FileMode.Append, FileAccess.Write);
// generate a file stream with UTF8 characters
sw = new StreamWriter(fs, System.Text.Encoding.UTF8);
sw.WriteLine(sMessage);
sw.Close();
sw = null;
}
else
{
StreamWriter sw = null;
//Open File
FileStream fs = new FileStream(Path.Combine(filePath, fileName), FileMode.Create, FileAccess.Write);
// generate a file stream with UTF8 characters
sw = new StreamWriter(fs, System.Text.Encoding.UTF8);
sw.WriteLine(sMessage);
sw.Close();
sw = null;
}
}
catch (Exception e)
{
MIEventLogs.WriteLog( e.ToString());
}
}
private static void MoveInputFile(string sFileName)
{
string strSourceFullFileName = "";
string strDestFullFilename = "";
string movedFromFolder= AppConfigValues.GetAppConfigValue("XmlFilePath");
string movedToFolder = AppConfigValues.GetAppConfigValue("InputPath");
System.IO.DirectoryInfo objdestfolder = new System.IO.DirectoryInfo(movedToFolder);
System.IO.DirectoryInfo getsourceFile = new System.IO.DirectoryInfo(movedFromFolder);
string sourcePath = "";
string DestPath = "";
try
{
sourcePath = getsourceFile.FullName;
if (sourcePath[sourcePath.Length - 1] != '\\')
sourcePath += "\\";
if (File.Exists(sourcePath + sFileName))
strSourceFullFileName = sourcePath + sFileName;
DestPath = objdestfolder.FullName;
if (DestPath[DestPath.Length - 1] != '\\')
DestPath += "\\";
strDestFullFilename = DestPath + sFileName;
if ((File.Exists(strSourceFullFileName) == true) && (objdestfolder.Exists == true))
{
if (File.Exists(strDestFullFilename))
{
File.Delete(strDestFullFilename);
}
File.Move(strSourceFullFileName, strDestFullFilename);
}
else
{
throw new System.ApplicationException("Invalid destination folder to move retry file.");
}
}
catch (System.Exception ex)
{
}
finally
{
}
}
}
}
You need to hand off the client to another thread or task while you wait for a new client.
I suggest you change this code to be fully asynchronous, using tasks and await. Something like this should work.
public static Task GetXMLStream(CancellationToken cancel)
{
Int32 port = Int32.Parse(AppConfigValues.GetAppConfigValue("Port"));
IPAddress localAddr = IPAddress.Parse(AppConfigValues.GetAppConfigValue("IPAddress"));
using (var server = new TcpListener(localAddr, port))
{
server.Start();
while (!cancel.IsCancellationRequested)
{
TcpClient client = await server.AcceptTcpClientAsync(cancel);
Task.Run(async () => await ProcessClient(client, cancel));
}
server.Stop();
}
}
private static async Task ProcessClient(TcpClient client, CancellationToken cancel)
{
using (client)
using (NetworkStream stream = client.GetStream())
{
try
{
await LoopClientStream(stream, cancel);
}
catch (OperationCanceledException)
{ //
}
catch (SocketException e)
{
MIEventLogs.WriteLog("SocketException: {0}" + e);
}
}
}
Your code that reads the stream and writes it to a file should also be fully asynchronous. I will leave that to you. Make sure you pass the CancellationToken to each asynchronous function.
You should also be aware that the stream may not return </Rec> in a single read, it may be split over separate reads. You may want to find a better way of tracking the end of each packet of data

How do I send and receive a file through tcp socket

Now I know that this question has been asked a lot but I really just don't get how to do it. I tried this but the file don't get complete I just receive just a bit of the file and the rest is just NULL here is my code in client part I first send a message to the server that contain the file size like this :
// here I send the a upload request with the size of the file that I want to send
byte[] data = Encoding.Unicode.GetBytes("uploadreq~"+new FileInfo(ofg.FileName).Length);
// here is the socket client
target.Send(data);
Then on the server side :
if (cmd.Contains(update.update_request))
{
// here I set an int var to the file size
update.update_size = int.Parse(cmd.Split('~')[1]);
// here I setup the a new byte array with the given file size
update.update_received = new byte[update.update_size];
// then I send a upload confirm command
Connection.sendCommand(Commands.update_confirme);
update.isupdate = true;
}
Again on the client side when the confirmation has been received :
if (cmd.StartsWith("updateConfirm"))
{
// reading all the bytes of the file and sending them
byte[] datatosend = File.ReadAllBytes("the file path");
Connection.send_bytes(datatosend);
}
Finally on the client side :
private void receiveInfo()
{
byte[] buffer = new byte[999999];
int received = 0;
try
{
received = Connection.clientSocket.Receive(buffer);
}
catch (SocketException)
{
Connection.clientSocket.Close();
Connection.clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Connection.makeConnection();
}
if (received == 0)
return;
byte[] data = new byte[received];
Array.Copy(buffer, data, received);
if (update.isupdate == true)
{
// this calls a method that process the data received
update.process_update(data);
}
}
public static void process_update(byte[] data)
{
int writeSize = 0;
Buffer.BlockCopy(data, 0, update_received, writeSize, data.Length);
writeSize += data.Length;
if (update_received.Length == update_size)
{
using (FileStream fs = File.Create("the path to where the file shloud go"))
{
byte[] info = update_received;
fs.Write(info, 0, info.Length);
}
Array.Clear(update_received, 0, update_received.Length);
isupdate = false;
}
}
As I was writing this question I changed the buffer size in the receive info method and that seems to change stuff a bit but still, the file won't arrive fully..
Try this for the client:
private void SendFile(String FileName,String IPAddress,int Port )
{
System.Net.Sockets.TcpClient TcpClient = new System.Net.Sockets.TcpClient(IPAddress, Port);
System.Net.Sockets.NetworkStream NetworkStream = TcpClient.GetStream();
System.IO.Stream FileStream = System.IO.File.OpenRead(FileName);
byte[] FileBuffer = new byte[FileStream.Length];
FileStream.Read(FileBuffer, 0, (int)FileStream.Length);
NetworkStream.Write(FileBuffer, 0, FileBuffer.GetLength(0));
NetworkStream.Close();
}
and this is the code for the server:
private void ReceiveFile(String FilePath, int Port)
{
System.Threading.Thread WorkerThread = new System.Threading.Thread(() =>
{
System.Net.Sockets.TcpListener TcpListener = new System.Net.Sockets.TcpListener(System.Net.IPAddress.Any, 60000);
TcpListener.Start();
System.Net.Sockets.Socket HandlerSocket = TcpListener.AcceptSocket();
System.Net.Sockets.NetworkStream NetworkStream = new System.Net.Sockets.NetworkStream(HandlerSocket);
int BlockSize = 1024;
int DataRead = 0;
Byte[] DataByte = new Byte[BlockSize];
lock (this)
{
System.IO.Stream FileStream = System.IO.File.OpenWrite(FilePath);
while (true)
{
DataRead = NetworkStream.Read(DataByte, 0, BlockSize);
FileStream.Write(DataByte, 0, DataRead);
if (DataRead == 0)
{
break;
}
}
FileStream.Close();
}
});
WorkerThread.Start();
}
This will only transfer one file.

TCP/IP data transfer freezes Unity while transferring the data

I am working on a unity project where user can send data from client to server using TCP/IP. I am able to send the data. But my unity stalls or freeze until the data got read from the networkstream.
Server Code:Read Data.
public void StartServer (){
// Start TcpServer background thread
tcpListenerThread = new Thread (new ThreadStart(ListenForIncomingRequests));
tcpListenerThread.IsBackground = true;
tcpListenerThread.Start();
startServerButton.interactable = false;
path = UnityEditor.EditorUtility.SaveFolderPanel ("Any type of File.", "", ""); // Path.Combine(path,"D:\\Siva\\TCPDownloadfiles");
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.Space)) {
SendMessage();
}
}
/// <summary>
/// Runs in background TcpServerThread; Handles incoming TcpClient requests
/// </summary>
private void ListenForIncomingRequests () {
Thread threadForDownloading = new Thread (new ThreadStart(DownloadingStreamData));
threadForDownloading.IsBackground = true;
threadForDownloading.Start();
//DownloadingStreamData ();
}
private void DownloadingStreamData()
{
try {
fileCount++;
int fileNameLen;
byte[] incomingData = new byte[1024];
string ext = "";
// Create listener on localhost port 8052.
tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 8052);
tcpListener.Start();
Debug.Log("Server is listening");
bytes = new Byte[Int32.MaxValue]; // 2221024
while (true) {
using (connectedTcpClient = tcpListener.AcceptTcpClient()) {
// Get a stream object for reading
using (stream = connectedTcpClient.GetStream()) {
Debug.Log("Befor Stream Read..........");
IAsyncResult result = stream.BeginRead(bytes, 0, bytes.Length, MessageReceived, stream);
result.AsyncWaitHandle.WaitOne();
// Read incoming stream into byte arrary.
do{
//length = stream.Read(bytes, 0, bytes.Length);
//length = s_bytesReceived;
Debug.Log("After Stream Read.........."+length);
incomingData = new byte[length];
Array.Copy(bytes, 0, incomingData, 0, length - 4);
// Convert byte array to string message.
fileNameLen = BitConverter.ToInt32(incomingData, 0);
string clientMessage = Encoding.ASCII.GetString(incomingData,4, fileNameLen);
ext = Path.GetExtension(clientMessage);
//Debug.Log("client message received as: " + clientMessage);
//File.WriteAllBytes(path + "\\temp"+fileCount.ToString()+ext, incomingData);
BinaryWriter bWrite = new BinaryWriter(File.Open(path + "\\temp"+fileCount.ToString()+ext, FileMode.Create)); ;
bWrite.Write(incomingData, 4 + fileNameLen, length - 4 - fileNameLen);
bWrite.Flush();
bWrite.Close();
} while(stream.DataAvailable);
//Debug.Log("Bytes length2 :>>>"+" "+fileNameLen +" Incoming data length" +incomingData.Length);
//connectedTcpClient.Close();
//stream.Flush();
//stream.Close();
//Debug.Log("GETTING FILE NAME THROUGH BUFFER ::"+stream);
}
}
}
}
catch (SocketException socketException) {
Debug.Log("SocketException " + socketException.ToString());
}
}
I tried using stream.BeginRead method but that is throwing exception like Stream/socket was disposed already and trying to access it on client code.
But stream.Read method works as like i expect but it stalls/freeze the unity until it get the data.Please give me some better solution for this issue. Thanks in advance.
Client Code: Sends Data
if (stream.CanWrite) {
string path = UnityEditor.EditorUtility.OpenFilePanel ("Any type of File.", "", "");
WWW www = new WWW ("file:///" + path);
byte[] fileNameBytes = Encoding.ASCII.GetBytes(path);
byte[] fileDataBytes = www.bytes;
byte[] fileNameLength = BitConverter.GetBytes(fileNameBytes.Length);
clientData = new byte[4 + fileNameBytes.Length + fileDataBytes.Length];
fileNameLength.CopyTo(clientData, 0);
fileNameBytes.CopyTo(clientData, 4);
fileDataBytes.CopyTo(clientData, 4 + fileNameBytes.Length);
Debug.Log ("FIle sends to server path : "+path);
//stream.BeginRead(clientData, 0, clientData.Length, MessageReceived, stream);
try {
stream.Write(clientData, 0, clientData.Length);
//stream.BeginWrite(clientData, 0, clientData.Length, MessageReceived, stream);
}catch (Exception e) {
Debug.Log("SocketException " + e.ToString());
}

tcp/ip recieve bytes and convert to texture

I have a small problem with this. I have another program / software which converts image to bytes and sends them on. So what I need to do now is catch those bytes in Unity and convert them back to image and set that as a texture.
I've already established the connection to the other software via TCP/IP system, connection is working, other software is sending data, but I've got no idea how to convert those bytes to img.
Debug.Log("client message received as: " + clientMessage);
is just a test so I can see that data is coming through.
Here is my code
img.LoadRawTextureData(Loader);
img.Apply();
GameObject.Find("Plane").GetComponent<Renderer>().material.mainTexture = img;
//
private void ListenForIncommingRequests()
{
try
{
tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 35800);
tcpListener.Start();
Debug.Log("Server is listening");
Byte[] bytes = new Byte[1024];
while (true)
{
using (connectedTcpClient = tcpListener.AcceptTcpClient())
{
using (NetworkStream stream = connectedTcpClient.GetStream())
{
int length;
while ((length = stream.Read(bytes, 0, bytes.Length)) != 0)
{
var incommingData = new byte[length];
Array.Copy(bytes, 0, incommingData, 0, length);
Loader = incommingData;
string clientMessage = Encoding.ASCII.GetString(incommingData);
Debug.Log("client message received as: " + clientMessage);
}
}
}
}
}
catch (SocketException socketException)
{
Debug.Log("SocketException " + socketException.ToString());
}
}
Have you tried passing the bytes into LoadRawTextureData?
private byte[] ListenForIncommingRequests()
{
try
{
tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 35800);
tcpListener.Start();
Debug.Log("Server is listening");
Byte[] bytes = new Byte[1024];
while (true)
{
using (connectedTcpClient = tcpListener.AcceptTcpClient())
{
using (NetworkStream stream = connectedTcpClient.GetStream())
{
int length;
while ((length = stream.Read(bytes, 0, bytes.Length)) != 0)
{
var incommingData = new byte[length];
Array.Copy(bytes, 0, incommingData, 0, length);
Loader = incommingData;
string clientMessage = Encoding.ASCII.GetString(incommingData);
Debug.Log("client message received as: " + clientMessage);
}
}
}
}
}
catch (SocketException socketException)
{
Debug.Log("SocketException " + socketException.ToString());
}
return bytes;
}
And call it like this.
var result = ListenForIncommingRequests();
img.LoadRawTextureData(result);
img.Apply();
GameObject.Find("Plane").GetComponent<Renderer>().material.mainTexture = img;

Sending image from C# Server to Java client through TCP socket

I have an image in my server which I want to send to my Java client through sockets. In c# I converted to byte array and then tried to send over the socket. But, a byte array in C# is unsigned so I tried to send signed byte array sbyte[] but it cannot be send by clientSocket.Send() method. On the java client side, I need to convert the byte array received to an Image object. Here is the exception trace that I get, at Image image = reader.read(0, param). Please help me with this.
Exception in thread "main" javax.imageio.IIOException: Bogus marker length
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
at ServerByteStreamWithoutOIS.main(ServerByteStreamWithoutOIS.java:54)
Here is my C# server code:
class Program
{
static void Main(String[] args)
{
Socket sListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 2. Fill IP
IPAddress IP = IPAddress.Parse("147.174.117.187");
IPEndPoint IPE = new IPEndPoint(IP, 20229);
// 3. binding
sListen.Bind(IPE);
// 4. Monitor
Console.WriteLine("Service is listening ...");
sListen.Listen(2);
// 5. loop to accept client connection requests
while (true)
{
Socket clientSocket;
try
{
clientSocket = sListen.Accept();
}
catch
{
throw;
}
// send the file
byte[] buffer = ReadImageFile("1.jpg");
clientSocket.Send(buffer, buffer.Length, SocketFlags.None);
clientSocket.Close();
Console.WriteLine("Send success!");
}
}
private static byte[] ReadImageFile(String img)
{
FileInfo fileInfo = new FileInfo(img);
byte[] buf = new byte[fileInfo.Length];
FileStream fs = new FileStream(img, FileMode.Open, FileAccess.Read);
fs.Read(buf, 0, buf.Length);
fs.Close();
//fileInfo.Delete ();
GC.ReRegisterForFinalize(fileInfo);
GC.ReRegisterForFinalize(fs);
return buf;
}
}
}
Here is my Java client:
public class ServerByteStreamWithoutOIS {
public static void main(String[] args) throws IOException, ClassNotFoundException{
int port = 20229;
Socket sock = null;
InetAddress addr = null;
addr = InetAddress.getByName("147.174.117.187");
sock = new Socket(addr, port);
System.out.println("created socket!");
int count = 0;
while(true){
String line = "";
String realLine = "";
BufferedReader bReader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
byte[] buffer = null;
while((line=bReader.readLine() )!=null){
realLine = realLine + line;
System.out.println(line.getBytes());
}
buffer = realLine.getBytes();
//buffer = (byte[])ois.readObject();
ByteArrayInputStream bis = new ByteArrayInputStream(buffer);
Iterator<?> readers = ImageIO.getImageReadersByFormatName("jpg");
ImageReader reader = (ImageReader) readers.next();
Object source = bis; // File or InputStream, it seems file is OK
ImageInputStream iis = ImageIO.createImageInputStream(source);
//Returns an ImageInputStream that will take its input from the given Object
reader.setInput(iis, true);
ImageReadParam param = reader.getDefaultReadParam();
Image image = reader.read(0, param);
//got an image file
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
//bufferedImage is the RenderedImage to be written
Graphics2D g2 = bufferedImage.createGraphics();
g2.drawImage(image, null, null);
File imageFile = new File("image.bmp");
ImageIO.write(bufferedImage, "bmp", imageFile);
System.out.println(imageFile.getPath());
//Thread.sleep(100);
System.out.println("Done saving");
}
}
}
I believe the error is because you are converting the bytes received in the Java server to a string representation. This can result in an error because a jpg is binary data, and when some binary data can not be converted to a character in a string, some conversion occurs which will result in an error when you use the getBytes() function.
If you instead read the bytes from the inputstream using the read(byte[],int,int]) function, I think you should be alright.
http://download.oracle.com/javase/1.5.0/docs/api/java/io/InputStream.html#read(byte[], int, int)
Edit, added a working code example
The "problem" of Java having signed bytes is a non issue. In binary they are the same bits, so when written to a file, the same bits are written since they are still the same order.
I wrote an example of a C# client and a Java server that I got working. I'm sure you can find it of use.
Server – Java
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ImageServer {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(8000);
Socket accept = server.accept();
InputStream inputStream = accept.getInputStream();
BufferedInputStream stream = new BufferedInputStream(inputStream);
int length = readInt(inputStream);
byte[] buf = new byte[length];
for (int read = 0; read < length; ) {
read += stream.read(buf, read, buf.length - read);
}
stream.close();
FileOutputStream fos = new FileOutputStream("image.png");
fos.write(buf, 0, buf.length);
fos.flush();
fos.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
private static int readInt(InputStream inputStream) throws IOException {
byte[] buf = new byte[4];
for (int read = 0; read < 4; ) {
read += inputStream.read(buf, 0, 4);
}
return toInt(buf);
}
public static int toInt(byte[] b) {
return (b[0] << 24)
+ ((b[1] & 0xFF) << 16)
+ ((b[2] & 0xFF) << 8)
+ (b[3] & 0xFF);
}
}
Client – C#
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
namespace Test.SendImageClient {
public class Program {
public static void Main(string[] args) {
if (args.Length == 0) {
Console.WriteLine("usage: client imagefile");
return;
}
FileStream stream = File.OpenRead(args[0]);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect("localhost", 8000);
int length = IPAddress.HostToNetworkOrder((int)stream.Length);
socket.Send(BitConverter.GetBytes(length), SocketFlags.None);
byte[] buffer = new byte[1024];
int read;
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) {
socket.Send(buffer, 0, read, SocketFlags.None);
}
socket.Close();
}
}
}
it seems like the bytes being received are not lining up w/the jpeg specification (can't be deserialized properly). are you sure the file on the server exists and that the c# byte[] is getting filled properly? maybe try to write the file on the server before sending it through the socket to ensure that you are actually reading a valid jpeg on the server.

Categories

Resources