I did Client-Server chat over sockets and it works great. Now I want to enable the option for the server (Android phone) to take a screenshot from the client (PC application). Creating a screenshot works fine, but the transfer from the client to the server is interrupted every time.
CUSTOMER PARTY / SENDING:
Before I wrote the image directly to the output stream, but I get an error on the server side, and so I tried this way, but it is the same.
public class ClientScreenshotThread implements Runnable { // - Software Init - // private Socket transferSocket; private BufferedImage screenshot; private Robot robot; private BufferedWriter outToServer; private FileInputStream inStream; private DataOutputStream outStream; // - Var Init - // private final int SERVER_TRANSFER_PORT = 65000; private int screenWidth, screenHeight; // -------------------------------------------------- // public ClientScreenshotThread() { } @Override public void run() { try { SocketAddress sockaddr = new InetSocketAddress(Client.SERVER_IP, SERVER_TRANSFER_PORT); transferSocket = new Socket(); transferSocket.connect(sockaddr, 5000); // 5sec Timeout Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize(); robot = new Robot(); screenWidth = dimension.width; screenHeight = dimension.height; Rectangle screen = new Rectangle(screenWidth, screenHeight); screenshot = robot.createScreenCapture(screen); ImageIO.write(screenshot, "png", new File("/Users/chris/Downloads/screenshot.png")); File file = new File("/Users/chris/Downloads/screenshot.png"); inStream = new FileInputStream(file); byte[] buffer = new byte[4096]; // prepare server for receiving the screenshot outToServer = new BufferedWriter(new OutputStreamWriter(transferSocket.getOutputStream())); outToServer.write("#!<cmd>screenshot"); outToServer.newLine(); outToServer.flush(); // send the screenshot to the server outStream = new DataOutputStream(transferSocket.getOutputStream()); int n; int i = 0; while((n = inStream.read(buffer)) != -1) { i++; System.out.println(i + ". Byte[" + n + "]"); outStream.write(buffer, 0, n); outStream.flush(); } } catch(AWTException e1) { System.out.println("AWT: " + e1.getMessage().toString()); } catch(IOException e2) { System.out.println("IO: " + e2.getMessage().toString()); } finally { try { // close streams and socket inStream.close(); outToServer.close(); transferSocket.close(); } catch(IOException e) { System.out.println(e.getMessage().toString()); } } } }
SERVER / RECEIVER:
I always get a "NullPointerException" at:
bmp.compress (Bitmap.CompressFormat.PNG, 100, fileOutStream);
public class ServerTransferThread implements Runnable { // - Software Init - // private ServerSocket serverTransferSocket; private Handler handler; private BufferedReader inFromClient; private DataInputStream inStream; private ByteArrayOutputStream content; private FileOutputStream fileOutStream; // - Var Init - // private final String TAG = "xxx"; private final int SERVER_TRANSFER_PORT = 65000; // -------------------------------------------------- // public ServerTransferThread(Handler _handler) { this.handler = _handler; } @Override public void run() { Log.d(TAG, "ServerTransferThread: run()"); try { serverTransferSocket = new ServerSocket(SERVER_TRANSFER_PORT); while(ServerActivity.SERVER_STATE == true) { Socket socket = serverTransferSocket.accept(); Log.d(TAG, "ServerTransferThread: accepted()"); inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream())); Log.d(TAG, "ServerTransferThread: bufferedReader()"); String message = ""; if((message = inFromClient.readLine()) != null) { if(message.equals("#!<cmd>screenshot")) { receiveScreenshot(socket); } } } } catch(IOException e) { Log.e(TAG, "ServerTransferThread 1: " + e.getMessage().toString()); } finally { try { inFromClient.close(); serverTransferSocket.close(); } catch (IOException e) { Log.e(TAG, "ServerTransferThread 2: " + e.getMessage().toString()); } } } private void receiveScreenshot(Socket socketX) { Log.d(TAG, "ServerTransferThread: receiveScreenshot()"); try { handler.sendMessage(buildMessage("> Receiving screenshot..")); inStream = new DataInputStream(socketX.getInputStream()); byte[] buffer = new byte[4096]; content = new ByteArrayOutputStream(); inStream = new DataInputStream(socketX.getInputStream()); int n; while((n = inStream.read()) != -1) { content.write(buffer, 0, n); // HERE I "OUT OF MEMORY" content.flush(); } File directory = new File(ServerActivity.APP_FOLDER_PATH); File screenshot = new File(ServerActivity.APP_FOLDER_PATH + "/" + "screenshot.png"); if(!directory.exists()) directory.mkdirs(); if(!screenshot.exists()) { screenshot.createNewFile(); } else { screenshot.delete(); screenshot.createNewFile(); } fileOutStream = new FileOutputStream(screenshot); Bitmap bmp = BitmapFactory.decodeByteArray(content.toByteArray(), 0, content.size()); bmp.compress(Bitmap.CompressFormat.PNG, 100, fileOutStream); handler.sendMessage(buildMessage("> Screenshot received sucessfully!")); } catch(IOException e1) { Log.e(TAG, "ServerTransferThread 3: " + e1.getMessage().toString()); } finally { try { inStream.close(); content.close(); fileOutStream.close(); socketX.close(); } catch (IOException e) { Log.e(TAG, "ServerTransferThread 4: " + e.getMessage().toString()); } } } private Message buildMessage(String text) { Log.d(TAG, "ServerTransferThread: buildMessage()"); Message msg = handler.obtainMessage(); Bundle bundle = new Bundle(); bundle.putString("MESSAGE", text); msg.setData(bundle); return msg; }
Here is my Logcat output:
08-20 19:01:18.285: D/skia(5383): --- SkImageDecoder::Factory returned null 08-20 19:01:18.295: W/dalvikvm(5383): threadid=12: thread exiting with uncaught exception (group=0x40c6b1f8) 08-20 19:01:18.295: E/AndroidRuntime(5383): FATAL EXCEPTION: Thread-3051 08-20 19:01:18.295: E/AndroidRuntime(5383): java.lang.NullPointerException 08-20 19:01:18.295: E/AndroidRuntime(5383): at net.api.speak.wifi.ServerTransferThread.receiveScreenshot(ServerTransferThread.java:114) 08-20 19:01:18.295: E/AndroidRuntime(5383): at net.api.speak.wifi.ServerTransferThread.run(ServerTransferThread.java:58) 08-20 19:01:18.295: E/AndroidRuntime(5383): at java.lang.Thread.run(Thread.java:856) 08-20 19:01:27.820: D/Speak WiFi(5383): Server: onDestroy() 08-20 19:01:27.830: E/Speak WiFi(5383): Server: Socket closed 08-20 19:01:27.830: E/Speak WiFi(5383): ServerThread: Socket closed
EDIT: After some problems, I found a final solution to the file transfer problem! There he is:
End side of the server:
int bytecount = 2048; byte[] buf = new byte[bytecount]; OutputStream OUT = socket.getOutputStream(); BufferedOutputStream BuffOUT = new BufferedOutputStream(OUT, bytecount); FileInputStream in = new FileInputStream(itemPath); int i = 0; while ((i = in.read(buf, 0, bytecount)) != -1) { BuffOUT.write(buf, 0, i); BuffOUT.flush(); }
End customer side:
FileOutputStream outToFile = new FileOutputStream(FileName); int bytecount = 2048; byte[] buf = new byte[bytecount];