DRE
DRE

Reputation: 323

Send Image from Java TCP Client to Node.js TCP Server

I am trying to send an image from java TCP Client to Node.js TCP Server i have tried to: send binary data, send base64 encoded binary data,send utf-8 encoded strings and at the moment nothing has worked, i always got the data and it creates the image(using fs), but its always corrupted. Here is my code:

JAVA CLIENT:

import java.util.*;
import java.io.*;
import java.net.Socket;

public class client{

    public static void main(String[] args) throws Exception {
        Socket client = new Socket("localhost",8080);
        Scanner scanner = new Scanner(System.in);
        String path= scanner.nextLine();
        FileInputStream fis = new FileInputStream(path);
        byte[] buffer = new byte[fis.available()];
        fis.read(buffer);
        buffer= Base64.getEncoder().encode(buffer);
        System.out.println(buffer.length);
        ObjectOutputStream oos= new ObjectOutputStream(client.getOutputStream());
        oos.writeObject(buffer);
        client.close();
    }
}

Node.js Server:

var fs = require('fs');
var net = require('net');
var sockets = [];
var server=net.createServer().listen(8080,"localhost");

server.on('connection', function(socket){
    console.log('Someone connected.');
    sockets.push(socket);
    var imageData;

    socket.on('data',function(data){
        imageData+= Buffer.from(data, 'base64');
    });

    socket.on('end',function(){
        console.log(imageData.length)
        fs.writeFileSync(new Date()+".png", imageData, function (err) {
          if (err) throw err;
          else  console.log('Saved!');
        });
    });

    socket.on('close',function(){
        console.log("Someone disconnected.");
    });
});

please i need help, its the fourth time i made this question and nobody answers me, or they say something that doesn't help and give me -1.

Here is the image output

UPDATE:
I tried working with strings and i first detected that the data length when received is not equal of the data length sent, so i removed the data in excess and still didn't work, i am thinking that fs library is bugged, can someone suggest me a better library that works with file in Node.js?

Upvotes: 2

Views: 1210

Answers (2)

Marco Fincato
Marco Fincato

Reputation: 163

There are a couple of errors that are causing the problem.

First of all, in your sender code, you're using an ObjectOutputStream which, as the name suggests, is made for sending objects. What you need is instead the DataOutputStream, which is made for primitive data types. It's also a lot faster than ObjectOutputStream since it has to handle fewer situations.

So the first change will be something like this:

DataOutputStream oos= new DataOutputStream(client.getOutputStream());
oos.write(buffer);

The next problem is on the receiving side. The socket.on('data') event happens many times during transmission, even if we're receiving the same string! This means that you'll have to wait for the transmission to finish before decoding from base64 to raw data. Another mistake you've made is not initializing the imageData var when creating it.

Let's see the code to make everything more clear. First of all, declaring imageData:

var imageData = "";

Now we know it is for sure an empty string. Next, receiving data:

socket.on('data',function(data){
    imageData += data;
});

As you can see I'm not decoding data here anymore, because it must be done after receiving everything. Last thing, decoding:

socket.on('end',function(){
    console.log(imageData.length)
    var decoded = Buffer.from(imageData, 'base64');
    fs.writeFileSync(new Date()+".png", decoded, function (err) {
        if (err) throw err;
        else  console.log('Saved!');
    });
});

The decoding now is done during the end event, when we have the entire string.

I've tried this and it's working fine now.

Upvotes: 1

Milad Aghamohammadi
Milad Aghamohammadi

Reputation: 1976

I think you are convert image data to base64 in java client, then convert base64 string to base64 again in server.js .

socket.on('data',function(data){
        let imageData=Buffer.from(data, 'base64');
        fs.writeFileSync(new Date()+".png", imageData, function (err) {
            if (err) throw err;
            else  console.log('Saved!');
        }); 
    });

Upvotes: 0

Related Questions