I am implementing a server in java which recieves images from an android application. basically it is recieving image from android emulator but not from android device. This all process of recieving an image from android emulator or android device is done on localhost.
here is my code of the server.
public class Server {
private static ServerSocket serverSocket;
private static Socket clientSocket;
private static InputStreamReader inputStreamReader;
private static BufferedReader bufferedReader;
private static String message;
private static byte[] image;
public static void main(String[] args) throws UnknownHostException, IOException {
try {
serverSocket = new ServerSocket(4000); // Server socket
} catch (IOException e) {
System.out.println("Could not listen on port: 4000");
}
System.out.println("Server started. Listening to the port 4000");
while (true) {
clientSocket = serverSocket.accept(); // accept the client connection
inputStreamReader = new InputStreamReader(clientSocket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader); // get the client message
DataInputStream inputFromClient = new DataInputStream(clientSocket.getInputStream());
int count = inputFromClient.available();
System.out.println(count);
image = new byte[count];
inputFromClient.readFully(image);
final BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(image));
ImageIO.write(bufferedImage, "jpg", new File("image.jpg"));
}
}
Exception
Exception in thread "main" javax.imageio.IIOException: Error reading PNG image data
at com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1308)
at com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1577)
at javax.imageio.ImageIO.read(ImageIO.java:1448)
at javax.imageio.ImageIO.read(ImageIO.java:1352)
at server.Server.main(Server.java:39)
Caused by: java.io.EOFException: Unexpected end of ZLIB input stream
at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:240)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)
at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
at java.io.DataInputStream.readFully(DataInputStream.java:195)
at com.sun.imageio.plugins.png.PNGImageReader.decodePass(PNGImageReader.java:1092)
at com.sun.imageio.plugins.png.PNGImageReader.decodeImage(PNGImageReader.java:1196)
at com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1301)
... 4 more
Java Result: 1
I am getting an exception of javax.imageiio.exception in case of sending an image from android device but for android emulator it is working fine. Kindly help me out plz. Thank You.
Your main problem is located in this line:
int count = inputFromClient.available();
It returns the number of bytes that are already received at that time. However there may be more bytes waiting to be transferred on the server side.
Therefore the transmitted image is truncated/incomplete when you try to load it.
You have now two choices:
Before transferring the image data send an integer containing the length of the data
If only one image is transferred close the stream on client side after the image has been written. On server side you now have to read until you reach the end of the stream.
Related
In my simple Java Client-Server program, when sending a message to the server and reading it there, readInt() reads indefinitely, making the program stick there.
I made sure I was only sending and receiving an int, nothing else, as you can tell by the code (I also tried with and without appending \n to the message sent to see if it would end):
Relevant Client Code
Socket server = new Socket("127.0.0.1", 2424);
DataOutputStream outputStream = new DataOutputStream(server.getOutputStream());
DataInputStream inputStream = new DataInputStream(server.getInputStream());
outputStream.writeInt(Protocol.Message.HANDSHAKE);
outputStream.write('\n'); // I tried with and without this
outputStream.flush();
Relevant Server Code
ServerSocket socket = new ServerSocket(2424);
System.out.println("Listening on port 2424");
while (connected) {
Socket client = socket.accept();
System.out.println("SERVER: Going to read a message"); // This shows
int messageType = (new DataInputStream(client.getInputStream())).readInt();
System.out.println("SERVER: Received a message (" + messageType + ")"); // This does not
commands.execute(messageType);
}
The message that should be printed after readInt() is never seen. I thought it would since I was only sending an int and receiving an int (4 bytes), it's not like I was sending more data than expected.
How should I go about making the readInt() end? Do I have to send a null byte or something else?
EDIT: Actual Server code (using Threads).
ServerSocket socket = new ServerSocket(2424);
System.out.println("Listening on port 2424");
while (connected) {
Socket client = socket.accept();
Worker worker = new Worker(client);
worker.start();
}
Worker Thread
public class Worker extends Thread {
private final Socket client;
private final Commands commands;
private final DataOutputStream outputStream;
private final DataInputStream inputStream;
public Worker(Socket client) throws IOException {
System.out.println("SERVER: Handling client message");
this.client = client;
outputStream = new DataOutputStream(client.getOutputStream());
inputStream = new DataInputStream(client.getInputStream());
commands = new Commands();
commands.addCommand(Protocol.Message.HANDSHAKE, new HandshakeCommand());
//commands.addCommand(Protocol.Message.RECEIVE_FILE, new ReceiveFileCommand());
}
#Override
public void run() {
System.out.println("SERVER: Running thread for client message");
try {
int messageType = inputStream.readInt();
System.out.println("SERVER: Received a message (ID " + messageType + ")");
commands.execute(messageType);
} catch (IOException | UnknownCommandException ex) {
System.out.println(ex);
}
}
}
The reason it was never reading is because nothing was being sent, as xander said.
And it was my fault I didn't include the actual client code, just the server code and a minimized version of the client code.
I was trying to send the message after the while() loop in the client (it also waits for messages from the server).
The solution was to delegate the the client's listening part into another thread so it didn't block the main thread that needed to send the message to the server.
I'm learning Java socket programming, and I'm pretty positive my code is correct, but for some reason the server and the client don't communicate. I'm not quite sure if they're even connecting. Here is what I've done so far.
Server:
public static void main(String[] args) throws Exception
{
Main_Server server = new Main_Server();
server.run();
}
public void run() throws Exception
{
ServerSocket server = new ServerSocket(444); //Port
Socket sSocket = server.accept();
BufferedReader bfr = new BufferedReader(new InputStreamReader(sSocket.getInputStream()));
String clientMessage = bfr.readLine();
System.out.println("Client: "+clientMessage);
if (clientMessage != null)
{
PrintStream ps = new PrintStream(sSocket.getOutputStream());
ps.println("Message Received.");
}
}
Client:
public static void main(String[] args) throws Exception
{
Client_One client = new Client_One();
client.run();
}
public void run() throws Exception
{
Socket clientSocket = new Socket("localhost", 444);
PrintStream ps = new PrintStream(clientSocket.getOutputStream());
ps.println("Hello, server.");
BufferedReader bfr = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String serverMessage = bfr.readLine();
System.out.println("Server: "+serverMessage);
}
So I run the server first and the client after (I'm currently using NetBeans IDE 8.1). The programs run and just sit there, but nothing happens after that. Why is this? I just have two empty consoles.
Thank you for your time.
If you use a Buffer you need to flush it or close it, otherwise if the buffer is not full the data remains in the buffer. It is ok also to close it because as you can see from the javadoc closing a stream will also flush it.
From the javadoc of OutputStream you can see what flushing means:
Flushes this output stream and forces any buffered output bytes to be written out.
Note: additionally remember to close both input and output streams when you finished to use them, otherwise you still have not properly closed resources using memory.
i am creating a desktop client server application, in which i am capturing the frames, in jpg images, rendered by the renderer and storing them on the client side.
now i need to upload the images to the server.
i tried this by
placing a separate thread for every captured image to upload it directly to the server but it was very time consuming. Also i tried to upload all the images from the client after the capturing is stopped, but that is not the case i want.
SO is there a way to upload the directly captured images to server effectievely.
for capturing images i am using BufferedImage and ImageIO.write methods
Thanks in advance
Image uploading Over socket is the fastest way to upload image on server because data will be passed to server as byte stream.
Below is simple Socket Client and Socket Sever to achieve Image upload
Client
public class ImageUploadSocketClient {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("localhost",6666);
OutputStream outputStream = socket.getOutputStream();
BufferedImage image = ImageIO.read(new File("path to image /your_image.jpg"));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", byteArrayOutputStream);
byte[] size = ByteBuffer.allocate(4).putInt(byteArrayOutputStream.size()).array();
outputStream.write(size);
outputStream.write(byteArrayOutputStream.toByteArray());
outputStream.flush();
socket.close();
}
}
Server
public class ImageUploadSocketRunnable implements Runnable{
public static final String dir="path to store image";
Socket soc=null;
ImageUploadSocketRunnable(Socket soc){
this.soc=soc;
}
#Override
public void run() {
InputStream inputStream = null;
try {
inputStream = this.soc.getInputStream();
System.out.println("Reading: " + System.currentTimeMillis());
byte[] sizeAr = new byte[4];
inputStream.read(sizeAr);
int size = ByteBuffer.wrap(sizeAr).asIntBuffer().get();
byte[] imageAr = new byte[size];
inputStream.read(imageAr);
BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageAr));
System.out.println("Received " + image.getHeight() + "x" + image.getWidth() + ": " + System.currentTimeMillis());
ImageIO.write(image, "jpg", new File(dir+System.currentTimeMillis()+".jpg"));
inputStream.close();
} catch (IOException ex) {
Logger.getLogger(ImageUploadSocketRunnable.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(13085);
while(true){
Socket socket = serverSocket.accept();
ImageUploadSocketRunnable imgUploadServer=new ImageUploadSocketRunnable(socket);
Thread thread=new Thread(imgUploadServer);
thread.start();
}
}
}
On server You should create different thread for different client socket in this way you can achieve concurrent image upload from different clients.
Hope above example will help you.
I'm writing an android app that sends an image to a server running a java app, and it's working in a very weird way!
Here is what I do
Compile and run the Java app on the desktop with the receive part that acts as server
Compile,deploy and run the android part that has to send the image to the server. The android app finishes execution but the java app doesn't
Run the android app activity that has the code to send the image AGAIN, and this time, the android app progress dialog gets stuck, BUT, the java app finishes execution and also the image is transferred d successfully...
Following is the code for the RECEIVE part of the Java app:
class ProjectServer
{
ServerSocket serSock;
Socket sock;
BufferedReader in;
PrintWriter out;
public static void main(String ar[])
{
try
{
ProjectServer cs=new ProjectServer();
cs.startServer();
}
catch(Exception e)
{
}
}
public void startServer()
{
try
{
serSock=new ServerSocket(8070);
System.out.println("Waiting for client...");
sock=serSock.accept();
System.out.println("Connections done");
//Accept File
System.out.println("Connected");
//receive code
int filesize=450660;
int bytesRead;
int current=0;
// receive file
byte [] mybytearray = new byte [filesize];
InputStream is = sock.getInputStream();
FileOutputStream fos = new FileOutputStream("C:\\Project Server\\Capture.png");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray, 0 , current);
bos.flush();
System.out.println("end-start");
}
catch(Exception e)
{
System.out.println(e);
e.printStackTrace();
}
}
}
Following is the code for the SEND part on the Android app:
package com.site.custom;
public class Act2 extends Activity
{
private ProgressDialog pd;
private String serverIP="58.146.100.187";
private BufferedReader in;
private PrintWriter out;
private String path;
private Socket cliSock;
public void onCreate(Bundle onCreateInstance)
{
super.onCreate(onCreateInstance);
setContentView(R.layout.act2);
this.setTitle("This has started");
path=getIntent().getStringExtra("path");
//Establish Connection
try
{
cliSock=new Socket(serverIP,8070);
in=new BufferedReader(new InputStreamReader(cliSock.getInputStream()));
((TextView)findViewById(R.id.tview)).setText(path);
}
catch(Exception e)
{
Log.v("MERA MSG",e.toString());
}
//Send file
ProgressDialog pd=ProgressDialog.show(this, "Sending image", "Image chosen:"+path.substring(path.lastIndexOf("//")+1),false,true);
try
{
File myFile = new File (path);
System.out.println((int)myFile.length());
byte[] mybytearray = new byte[450560];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = cliSock.getOutputStream();
System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();
System.out.println("Completed");
pd.dismiss();
System.out.println("Done");
}
catch(Exception e)
{
Log.v("MERA MSG",e.toString());
}
}
}
You're not closing any of the connections. Your Server is probably waiting until the connection is closed before it knows that data has finished being sent. When your Client runs the second time, the first connection is probably closed automatically by Android, this allowing your Server to process the image. However, if your Server doesn't process the image fast enough, maybe your Client gets 'stuck' on the second run because its waiting for the successful port connection to the Server but the Server is busy.
Long story short, how about you try to close() the Client connection when you're finished with it. Calling flush() doesn't really tell anything to the Server to say that the data has finished being sent.
If you want the socket to stay open even though you close the OutputStream, you could write a custom Socket that just overwrites the close() method, something like this...
public class MySocket extends Socket {
public MySocket(String ipAddress, int port){
super(ipAddress,port);
}
public void close(){
// do nothing
}
public void reallyClose(){
super.close();
}
}
In your code, change cliSock=new Socket(serverIP,8070); to cliSock=new MySocket(serverIP,8070);
When you call OutputStream.close(), it calls close() on MySocket, but as you can see it doesn't actually do anything. When you've completely finished with the Socket, you can call MySocket.reallyClose(); and it'll close it off properly.
EDIT: The code below throws no exception but has no output and hangs. It should output "Test message". In main(), we start a thread that's given a server socket listening on a random port. The main thread the tries to connect and communicate with the ServerSocket on that same random port, but is apparently failing. Why?
public class IntraProcSockTest {
private static int port;
private class Listener extends Thread {
public Listener() {
}
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(0);
port = serverSocket.getLocalPort();
Socket socket = serverSocket.accept();
BufferedReader in;
String fromClient;
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
while ((fromClient = in.readLine()) != null) {
System.out.println("From client: " + fromClient);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public IntraProcSockTest() {
new Listener().start();
}
public static void main(String[] args) {
new IntraProcSockTest();
try {
Thread.sleep(5000);
Socket socket = new Socket("localhost", port);
PrintWriter socketOut = new PrintWriter(socket.getOutputStream());
socketOut.println("Test message");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
A process can connect to a socket created by itself, there is no problem. Show us the code that throws an exception and/or more details about the exception.
First of all, be careful not to specify a local port for the client socket (the one connecting to the other which is listening). Let the OS choose a random port. Remember that any socket is identified by four elements (remote host, local host, remote port, local port), if you bind both the server socket and the client socket on the same local port, let it be 4498, both sockets are defined as follows: (localhost, localhost, 4498, 4498) and this doesn't work. I suspect this might be your problem.
To avoid such problems, client sockets are often bound to a random port, chosen by the OS. Show us your code, expecially the part in which the client sockets gets created and connects to the server socket.
And about IPC, it is not always bad to use sockets as an inter-process or even intra-process communication technique. The performance is worse, obviously, and you might loose some code readability, but your software will be easily portable to a network (distributed) application. It's up to your plans, it's not like IPC sockets == bad.
To create a Socket connection in one thread you can.
ServerSocket ss = new ServerSocket(0); // open a random free port.
Socket c = new Socket(ss.getInetAddress(), ss.getLocalPort());
Socket s = ss.accept();
ss.close();
final byte[] bytes = "Hello World!".getBytes();
final OutputStream out = c.getOutputStream();
out.write(bytes.length);
out.write(bytes);
final DataInputStream in = new DataInputStream(s.getInputStream());
int len = in.read();
final byte[] b = new byte[len];
in.readFully(b);
System.out.println(new String(b));
c.close();
s.close();
If all you want is IPC within a Process, a socket is not the fastest or simplest way to go. Try using a Pipe (NIO) or PipeInput/OutputStream (IO). Its faster and simpler.
Pipe pipe = Pipe.open();
SinkChannel sink = pipe.sink();
SourceChannel source = pipe.source();
or
PipedOutputStream output = new PipedOutputStream();
PipedInputStream input = new PipedOutputStream(output);
BTW: You can connect a client and server Socket in the same thread, however
Using an Exchanger is 10x faster, and using a ring buffer is faster again.
If you want convenience, using an ExecutorService is the best way to deleagte work to a background pool of threads. This can still perform millions of tasks per second.