Java sockets file sending - java

I am writing Client/Server using java sockets. There is my code:
SERVER:
public void sendFile(File file) {
BufferedOutputStreambufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
int count;
FileInputStream in;
try {
in = new FileInputStream(file);
byte[] mybytearray = new byte[(int) file.length()];
while ((count = in.read(mybytearray)) > 0) {
bufferedOutputStream.write(mybytearray, 0, count);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
CLIENT:
public void downloadFile() {
BufferedInputStream bufferedInputStream = new BufferedInputStream(socket.getInputStream());
byte[] aByte = new byte[8192];
int count;
FileOutputStream in;
try {
in = new FileOutputStream("C://fis.txt");
while ((count = bufferedInputStream.read(aByte)) > 0) {
System.out.println(count); // <- nothing happens
in.write(aByte, 0, count);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Why bufferedInputStream in 2nd function is empty ?

BufferedOutputStream will not write data until the buffer is full. You need to flush the OutputStream:
bufferedOutputStream.flush();

Related

How to send a bitmap using serversocket

I am making a multiplayer drawing application for android and I need to send the drawings that every user made to one player. I am using a server socket for this.
First thing I do is convert the Bitmap to a byte array, so I can send it to the Host with host.write(byteArray);
Bitmap bitmapImage = drawView.getBitmap();
byte[] byteArray = getByteArray(bitmapImage);
byteArrayLength = byteArray.length;
MainWifiActivity.SendReceive host = MainWifiActivity.sendReceiveHost;
if (host != null) {
host.write(byteArray);
}
The following code is my SendReceive class, which listenes to the inputStream and then starts a Handler, that is supposed to save the Bitmap to Internal Storage
public class SendReceive extends Thread {
private Socket socket;
private InputStream inputStream;
private OutputStream outputStream;
public SendReceive(Socket s) {
socket = s;
try {
inputStream = s.getInputStream();
outputStream = s.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;
int filesize;
while (socket != null) {
try {
filesize = DrawingActivity.byteArrayLength;
if(buffer.length != filesize && filesize > 0){
buffer = new byte[filesize];
}
bytes = inputStream.read(buffer,0 ,buffer.length);
if (bytes > 0) {
Message mesg = handler.obtainMessage(IMAGE_MSG, bytes, -1, buffer);
mesg.sendToTarget();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
And the Handler:
Handler handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case IMAGE_MSG:
byte[] byteArray = (byte[]) msg.obj;
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
saveBitmapToInternalStorage(bitmap);
}
return false;
}
});
In the saveBitmapToInternalStorage Method I get a java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference
private void saveBitmapToInternalStorage(Bitmap bmp) {
File directory = getApplicationContext().getDir("imageDir", Context.MODE_PRIVATE);
File myPath = new File(directory, UUID.randomUUID().toString() + ".png");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myPath);
bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (Exception e) {
Log.d("HELLO", "MY ERROR: " + e);
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I know that BitmapFactory.decodeByteArray returns the decoded bitmap, or null if the image could not be decoded.
But why could it not be decoded?
I think this piece is wrong
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myPath);
bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (Exception e) {
It should be
FileOutputStream fos = new FileOutputStream(myPath);
try {
bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (Exception e) {

How do I resume a file upload?

I am using plupload at JavaScript library.
I want to resume file uploads if there is a failure while implementing file uploads.
I've been told to use HTTP chunk transfer.
but I don't know, How can I use it.
please show following server-side code.
private static final int BUFFER_SIZE = 100 * 1024;
try {
Integer chunk = 0, chunks = 0;
if(null != request.getParameter("chunk") && !request.getParameter("chunk").equals("")){
chunk = Integer.valueOf(request.getParameter("chunk"));
}
if(null != request.getParameter("chunks") && !request.getParameter("chunks").equals("")){
chunks = Integer.valueOf(request.getParameter("chunks"));
}
logger.info("chunk:[" + chunk + "] chunks:[" + chunks + "]");
...
appendFile(file.getInputStream(), destFile, response);
if (chunk == chunks - 1) {
logger.info("upload success !");
}else {
logger.info("left ["+(chunks-1-chunk)+"] chunks...");
}
} catch (IOException e) {
logger.error(e.getMessage());
}
}
public void appendFile(InputStream in, File destFile, HttpServletResponse response) {
OutputStream out = null;
try {
if (destFile.exists()) {
out = new BufferedOutputStream(new FileOutputStream(destFile, true), BUFFER_SIZE);
} else {
out = new BufferedOutputStream(new FileOutputStream(destFile),BUFFER_SIZE);
}
in = new BufferedInputStream(in, BUFFER_SIZE);
int len = 0;
byte[] buffer = new byte[BUFFER_SIZE];
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
} catch (Exception e) {
logger.error(e.getMessage());
}
finally {
try {
if (null != in) {
in.close();
}
if(null != out){
out.close();
}
} catch (IOException e) {
e.getMessage();
logger.error(e.getMessage());
}
}
}

Catch 404 error from BufferedInputStream

I have a function for html page download.
Here is the code:
public class pageDownload {
public static void down(final String filename, final String urlString)
throws MalformedURLException, IOException {
BufferedInputStream in = null;
FileOutputStream fout = null;
try {
in = new BufferedInputStream(new URL(urlString).openStream());
fout = new FileOutputStream(new File(filename));
final byte data[] = new byte[1024];
int count;
while ((count = in.read(data, 0, 1024)) != -1) {
fout.write(data, 0, count);
}
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
} catch (IndexOutOfBoundsException e) {
System.err.println("IndexOutOfBoundsException: " + e.getMessage());
}
in.close();
fout.close();
}
}
Works ok, problem appears when i try to download a page that not exist. I can't figure out how to handle 404 error in this case.
Has anyone some idea?
Do you mean something like this? I added a finally to save close the Streams
public class pageDownload {
public static void down(final String filename, final String urlString)
throws MalformedURLException, IOException {
BufferedInputStream in = null;
FileOutputStream fout = null;
try {
in = new BufferedInputStream(new URL(urlString).openStream());
fout = new FileOutputStream(new File(filename));
final byte data[] = new byte[1024];
int count;
while ((count = in.read(data, 0, 1024)) != -1) {
fout.write(data, 0, count);
}
} catch(FileNotFoundException ex)
{
System.err.println("Caught 404: " + e.getMessage());
}
catch(IOException ex)
{
System.err.println("Caught IOException: " + e.getMessage());
}
catch(IndexOutOfBoundsException e)
{
System.err.println("IndexOutOfBoundsException: " + e.getMessage());
}
finally{
if(in != null)
try { in.close(); } catch ( IOException e ) { }
if(fout != null)
try { fout.close(); } catch ( IOException e ) { }
}
}
}
Your problem is you get a NullPointerException when you try to close the streams. You should anyway close them in a finally clause or use try with resources:
public static void down(final String filename, final String urlString)
throws IOException {
try (BufferedInputStream in = new BufferedInputStream(new URL(urlString)
.openStream());
FileOutputStream fout = new FileOutputStream(new File(filename))) {
final byte data[] = new byte[1024];
int count;
while ((count = in.read(data, 0, 1024)) != -1) {
fout.write(data, 0, count);
}
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
} catch (IndexOutOfBoundsException e) {
System.err.println("IndexOutOfBoundsException: " + e.getMessage());
}
}

Read form ZipDecryptInputStream and write it to OutputStream

public void decrypt(String inputFile, String password) {
ZipDecryptInputStream zipDecrypt = null;
try {
zipDecrypt = new ZipDecryptInputStream(new FileInputStream(
inputFile), password);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
File file = new File("outouttfile.tsv");
OutputStream fop = null;
try {
fop = new FileOutputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = zipDecrypt.read(buffer)) != -1) {
fop.write(buffer, 0, bytesRead);
System.out.println("Written");
}
} catch (IOException e) {
e.printStackTrace();
}
}
My while loop becomes an infinite loop and does not stop reading the file even its read once. Any idea why?

for loop doesn't receive full data

I got the problem that my program is stuck in the for loop because the dataInputSteam doesn't receive all data before the DataOutputSteam is finished.
In my program I want to send a secreenshot with the server and the client should receive it:
Server:
public sendScreen(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
Robot robot;
try {
robot = new Robot();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screen = new Rectangle( screenSize );
BufferedImage image = robot.createScreenCapture( screen );
BufferedImage scaledImage = Scalr.resize(image, 300);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "png", baos);
byte[] screenBytes = baos.toByteArray();
daos = new DataOutputStream(socket.getOutputStream());
daos.writeInt(screenBytes.length);
daos.write(screenBytes);
System.out.println("Screen sent");
} catch (AWTException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
And the client:
public static class GetScreenshot implements Runnable{
Socket socket;
private static DataInputStream din;
private static BufferedImage screenshot;
public GetScreenshot(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
System.out.println("start method getScreenshot");
int length;
byte[] buffer;
PrintWriter out;
try {
//sending command to send screenshot
out = new PrintWriter(socket.getOutputStream(), true);
out.println("GETSCREENSHOT");
din = new DataInputStream(socket.getInputStream());
System.out.println("DIS created");
length = din.readInt();
System.out.println("Got data from DIS");
buffer = new byte[length];
System.out.println("Filled buffer");
for(int i = 0; i < length; i++){
buffer[i] = (byte) din.read();
System.out.println("read" + i+ "while length is " + length + " read data " + buffer);
}
System.out.println("got buffer");
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
screenshot = ImageIO.read(bais);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//writing screenshot to local disk
File outputfile = new File("C:\\users\\XXXX\\documents\\image2.png");
try {
ImageIO.write(screenshot, "png", outputfile);
System.out.println("image written to local disk");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//set screenshot in the tool
Main.labelScreenshot.setIcon(new ImageIcon(screenshot));
}
}
Does anybody know how i can transfer all of the data of the screenshot?
Greetings
Max
I think your problem is because your view (canvas/label/etc) width & height is smaller than your image. Try to resize the screenshoot so the width & height is same as your view (canvas/label/etc).
buffer = new byte[length];
System.out.println("Filled buffer");
At this point this message is simply untrue. You have created the buffer, but you certainly haven't filled it.
for(int i = 0; i < length; i++){
buffer[i] = (byte) din.read();
System.out.println("read" + i+ "while length is " + length + " read data " + buffer);
}
All this is equivalent to:
din.readFully(buffer);
And then:
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
screenshot = ImageIO.read(bais);
//writing screenshot to local disk
File outputfile = new File("C:\\users\\XXXX\\documents\\image2.png");
try {
ImageIO.write(screenshot, "png", outputfile);
All this is entirely equivalent to:
try (new FileOutputStream out = new FileOutputStream("C:\\users\\XXXX\\documents\\image2.png"))
{
out.write(buffer);
}
There is no need to decode and re-encode the image.
You add this to the sender part:
socket.flush();
if not worked, then:
socket.shutdownOutput();

Categories