not able to get inputstream in server socket file transfer - java

I have developed a screen in swings to download a file from the server. The whole concept works fine when i click the download button once. But when i click the download button second time, i find that the code pauses in getting the inputstream.(this i have followed it using the sysouts shown.)
Below shown are the two separate code snippets in two different files. TCPClient has the serversocket codings whereas the clientUI has the ui components which calls the TCPSever method to accept a socket and for requesting purpose.
In the tcp client side:
public TCPClient() throws Exception{
System.out.println("Inside TCPClient constructor---");
clientSocket = new Socket("localhost", 3500);
System.out.println("After creating socket instance---");
oos = new ObjectOutputStream(clientSocket.getOutputStream());
System.out.println("after getting the ouput stream---");
ois = new ObjectInputStream(clientSocket.getInputStream());
System.out.println("after getting the input stream.");
}
In the Client UI:
private void downloadButton_actionPerformed(ActionEvent e) throws Exception
{
Object selectedItem = contentsList.getSelectedValue();
System.out.println("selectedItem---"+selectedItem);
new TCPClient().downloadContents(nodeName,selectedItem.toString());
}
}
Kindly provide me a solution for this...
Below is the server code:
public void listening() throws Exception{
ServerSocket ss = new ServerSocket(3500);
System.out.println( "DataServer Is Listening..." );
while( true )
{
Socket soc = ss.accept();
ObjectInputStream ois = new ObjectInputStream(soc.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream( soc.getOutputStream() );
String input = ( String ) ois.readObject( );
if(input.startsWith("downloadContents")){
String nodeName = ois.readObject().toString();
String contentName = ois.readObject().toString();
List contentsForNode = DBServer.getContentsForNode(nodeName);
for(Object obj : contentsForNode){
if(obj.toString().contains(contentName)){
new FileServer().send(obj.toString());
break;
}
}
}
}
}
public static void main( String[] args )
{
TCPServer obDataServer = new TCPServer();
try
{
obDataServer.listening();
}
catch ( Exception ioe )
{
ioe.printStackTrace();
}
}

At a guess, your server is single-threaded and is still reading its input stream, because you haven't closed the client socket. But it's anybody's guess until you post the relevant server code.

Do you take care of closing the socket after the file is downloaded (successfully/unsuccessfully)? It doesn't looks like it from the code snippet.
I'm not sure, but this might be the problem

This Is Server Class:
package client_to_server;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;`
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class Server {
public static void main(String args[])throws IOException
{
ServerSocket serverSocket=new ServerSocket(2222);
System.out.println("New Server is Waiting");
Socket socket=serverSocket.accept();
System.out.println("My Connection Established");
DateFormat df=new SimpleDateFormat("HH:mm:ss");
Calendar c=Calendar.getInstance();
String starttime=df.format(c.getTime());
System.out.println("Start time is : "+starttime);
InputStream inputStream=socket.getInputStream();
byte[] readbyte=new byte[(1024*20)*1024];
FileOutputStream fileOutputStream=new FileOutputStream("/home/Manoj/copybulkfile5.zip");
int writebyte;
int count=0;
while((writebyte=inputStream.read(readbyte))!=-1)
{
if(writebyte>0)
count+=writebyte;
fileOutputStream.write(readbyte, 0, writebyte);
}
DateFormat df1=new SimpleDateFormat("HH:mm:ss");
Calendar c1=Calendar.getInstance();
String endtime=df1.format(c1.getTime());
System.out.println("END TIME is "+endtime);
System.out.println("THE WRITEBYTE VALUE IS "+writebyte+"THE READ BYTE VALUE IS"+count);
inputStream.close();
}
}
This Is Client Cass:
package client_to_server;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
public static void main(String args[])throws IOException
{
//Socket socket=new Socket("localhost",2222);
Socket socket=new Socket("localhost",2222);
File file=new File("/home/Checking/Myfile.zip");
byte[] mybyte=new byte[(1024*20)*1024];
FileInputStream fileInputStream=new FileInputStream(file);
int count;
OutputStream outputStream=socket.getOutputStream();
while((count=fileInputStream.read(mybyte))!=-1)
{
outputStream.write(mybyte);
}
System.out.println("THIS FILE HAS BEEN SENT SUCCESSFULLY!!!");
//System.out.println("END TIME "+hr+"Hours"+min+"Minutes "+sec+"Seconds");
socket.close();
}
}

Related

How to fix: java.net.SocketException: An established connection was aborted by the software in your host machine

Minimal Reproducible Example
Server.java
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.ServerSocket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(12345, 3);
Socket socket = serverSocket.accept(); // incoming request
new WorkerThread(socket).start();
}
}
class WorkerThread extends Thread {
private Socket socket;
public WorkerThread(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.flush();
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); // line 28
// handle the request using oos and ois
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client.java
import java.net.Socket;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Client {
public static void main(String[] args) throws Exception {
try (Socket socket = new Socket("192.168.1.3", 12345)) {
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.flush();
// ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); // line 11
// send some data only using oos
}
}
}
Thrown Exception
java.net.SocketException: An established connection was aborted by the software in your host machine
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:325)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:966)
at java.base/java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2908)
at java.base/java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2924)
at java.base/java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:3421)
at java.base/java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:959)
at java.base/java.io.ObjectInputStream.<init>(ObjectInputStream.java:397)
at WorkerThread.run(Server.java:28)
The WorkerThread seems to be causing the issue, since the SocketException is not thrown if the code in the code of the WorkerThread#run method is placed in the Server#main method. See Note below.
The intent here is to have a separate Thread (other than the main Thread of the Server) handle each request as it comes, therefore the WorkerThread receives a reference to the Socket associated with the incoming connection.
The WorkerThread needs to open both oos and ois (even though they might not be both strictly needed for communication) because opening only the ois won't work. Further reading on why this happens.
What is the underlying cause of this issue? Is there a way to fix the problem other than the hacky (?) solution presented below?
Note
Running the above Client with this Server does not throw the Exception:
NonThreadedServer.java
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.ServerSocket;
public class NonThreadedServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(12345, 3);
Socket socket = serverSocket.accept(); // incoming request
try {
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.flush();
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
// handle the request using oos and ois
} catch (IOException e) {
e.printStackTrace();
}
}
}
Solution
Uncomment line 11 of Client, i.e. create an ObjectInputStream, even though it is not strictly needed for the communication:
Client.java
import java.net.Socket;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Client {
public static void main(String[] args) throws Exception {
try (Socket socket = new Socket("192.168.1.3", 12345)) {
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.flush();
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); // line 11
// send some data only using oos
}
}
}
As mentioned in the question, I don't know what the underlying issue is or whether this solution is the correct one. If it isn't, I'll make sure to mark another answer as the accepted one.

How do I send objects back and forth continuously across sockets in Java?

What I am trying to do here is create an application that will be a basic game, and first I have to get the networking functional. I'm struggling to send objects back and forth between server and client. The design I am trying to achieve is 2 processes with 2 threads each, the main thread and then a listener thread. I want the listener thread to listen for incoming objects, as this will be used for an event bus. Currently to get it working I'm using just a simple message class which holds a single string field called text. The issue I'm having is that the client listener thread doesn't seem to start, and the objects never get sent either way. Really struggling learning network programming here, any help is much appreciated.
Server side
package Server;
import java.net.*;
import java.util.List;
import Utilities.Message;
import java.io.*;
public class BattleshipServer
{
public static void executeThreadedServer(int port) throws Exception
{
ServerSocket server = new ServerSocket(port);
System.out.println("Awaiting connection");
Socket socket = server.accept();
System.out.println("Connection established");
BufferedReader kb = new BufferedReader(new InputStreamReader(System.in));
ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
//Start the listener thread
ServerListener sListener = new ServerListener(kb, out, in);
sListener.run();
Message msg = new Message("temp");
while(!msg.getText().equalsIgnoreCase("exit"))
{
msg = new Message(kb.readLine());
out.writeObject(msg);
out.flush();
}
}
}
------------------------------------------------------------------------------------------------------------
package Server;
import java.io.BufferedReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import Utilities.Message;
public class ServerListener implements Runnable
{
private BufferedReader keyBoard;
private ObjectOutputStream out;
private ObjectInputStream in;
public ServerListener(BufferedReader keyboard, ObjectOutputStream out, ObjectInputStream in)
{
this.keyBoard = keyboard;
this.out = out;
this.in = in;
}
#Override
public void run()
{
System.out.println("Server listener started");
try {
while(true)
{
Message msg;
while((msg = (Message)this.in.readObject()) != null)
{
System.out.println(msg.getText());
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Client Side
package Client;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
import Utilities.Message;
import java.io.*;
public class BattleshipClient
{
public static void executeThreadedClient(String address, int port) throws Exception
{
Socket socket = new Socket(address, port);
BufferedReader kb = new BufferedReader(new InputStreamReader(System.in));
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ClientListener cListener = new ClientListener(kb,out,in);
cListener.run();
Message msg = new Message("temp");
while(!msg.getText().equalsIgnoreCase("exit"))
{
msg = new Message(kb.readLine());
out.writeObject(msg);
out.flush();
}
socket.close();
}
}
------------------------------------------------------------------------------------------------------------
package Client;
import java.io.BufferedReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import Utilities.Message;
public class ClientListener implements Runnable
{
private BufferedReader keyBoard;
private ObjectOutputStream out;
private ObjectInputStream in;
public ClientListener(BufferedReader keyboard, ObjectOutputStream out, ObjectInputStream in)
{
this.keyBoard = keyboard;
this.out = out;
this.in = in;
}
#Override
public void run()
{
System.out.println("Client listener started");
try
{
while(true)
{
Message msg = (Message)in.readObject();
System.out.println(msg.getText());
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Although your ClientListener and ServerListeners are implementing Runnable, they are not run in a separate thread. In your implementation, it is just another function call and therefore the code after the listener.run() never gets called.
So instead of doing:
ClientListener cListener = new ClientListener(kb,out,in);
cListener.run();
You need to do something like:
Thread clientThread = new Thread(new ClientListener(kb,out,in));
clientThread.start();
And on the server side you need to do something similar.

Is there a possiblity to write/read from a socket on same port from different class

Im having Spring Boot Application for communication between Machines (tcp Clients) and TCP Server (localhost). I am able to communicate with one machine/client, but I cant communicate with 2 or more machines.
Therefore I start my Spring Boot Application:
package com.example.workflow;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.io.IOException;
#SpringBootApplication
public class Application {
public static void main(String[] args) throws IOException {
Runnable serverZyklisch = new ServerZyklisch();
Runnable serverAzyklisch = new ServerAzyklisch();
for (int i = 0; i < 4; i++) {
new Thread(serverZyklisch).start();
new Thread(serverAzyklisch).start();
}
SpringApplication.run(Application.class);
}
}
There I have different Threads started, so that the clients (for example 10.50.12.174 = Press, 10.50.12.204 = Drill) can connect to TCP Server over Socket Connection.
My ServerAzyklisch class is like this:
package com.example.workflow;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerAzyklisch implements Runnable, JavaDelegate {
int count = 0;
private final ServerSocket ssocket;
static String param = StartTCPServersDelegate.parameter;
HexToByteConverter hexToByteConverter = new HexToByteConverter();
// 2 TCP Server starten Port 2000, Port 2001
public ServerAzyklisch(String Pparam) throws IOException {
ssocket = new ServerSocket(2000);
param = Pparam;
}
public ServerAzyklisch() throws IOException {
ssocket = new ServerSocket(2000);
}
public void run() {
byte[] buf = new byte[1];
System.out.println(param+"Paraaam");
InputStream in;
OutputStream out = null;
Socket socket = null;
//Thread immer aktiv
int n = 0;
while(true){
try {
// Wartet auf Socket Verbindung
System.out.println("Server is listening on port "+ ssocket.getLocalPort());
socket = ssocket.accept();
count++;
System.out.println("Countet clients: "+count);
socket.setSoLinger(true, 1000);
System.out.println("Sockeport: "+socket.getLocalPort());
System.out.println("Connection from " + socket.getInetAddress().toString());
//Inputstream
in = socket.getInputStream();
//Outputstream
out = socket.getOutputStream();
//Datenpuffer deklarieren (anlegen)
byte []data = new byte[132];
byte[]Pressen1hexdump110 = hexToByteConverter.hexStringToByteArray("33333333003d0064000600000004004001c9c78900010000006e0000000000000000000000000001000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"+param);
byte[]Pressen2hexdump = hexToByteConverter.hexStringToByteArray("3333333300400065000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
byte[]Pressen3hexdump = hexToByteConverter.hexStringToByteArray("3333333300400065001400000000004001c9c6e900010000006e000000000000000000000000000100000000001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
in.read(buf);
while (buf[0] != -1) {
out.write(Pressen1hexdump110);
out.write(Pressen2hexdump);
out.write(Pressen3hexdump);
}
} catch (IOException e) {
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
public void execute(DelegateExecution delegateExecution) throws IOException {
}
}
Now I want to outsource the "while loop" (with out.write) in other Classes to use the connection to Socket like in ServerAzyklisch run method.
Therefore I wrote for example a Class Presse.java
package com.example.workflow;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Presse implements JavaDelegate {
ServerSocket ssocket;
private HexToByteConverter hexToByteConverter = new HexToByteConverter();
Socket socket;
InputStream in;
OutputStream out;
byte[]Pressen1hexdump110 = hexToByteConverter.hexStringToByteArray("33333333003d0064000600000004004001c9c78900010000006e00000000000000000000000000010000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005");
byte[]Pressen2hexdump = hexToByteConverter.hexStringToByteArray("3333333300400065000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
byte[]Pressen3hexdump = hexToByteConverter.hexStringToByteArray("3333333300400065001400000000004001c9c6e900010000006e000000000000000000000000000100000000001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
public Presse() throws IOException {
ssocket = new ServerSocket(2000);
socket = ssocket.accept();
//Inputstream
in = socket.getInputStream();
//Outputstream
out = socket.getOutputStream();
}
public void sendMessage(InputStream in, OutputStream out, byte[]message) throws IOException {
out.write(Pressen1hexdump110);
out.write(Pressen2hexdump);
out.write(Pressen3hexdump);
socket.close();
}
#Override
public void execute(DelegateExecution delegateExecution) throws Exception {
PostRequestDelegate postRequestDelegate = new PostRequestDelegate();
postRequestDelegate.post();
}
}
I want to send my 3 messages from this class, like in ServerAzyklisch class. But it throws Error because:
Caused by: java.net.BindException: Address already in use: NET_Bind
I know this because is I do Socket.accept a second time, but I dont understand how I can achieve this to work. Do I have to close socket connection ? If yes where and with which Java Command ?
If you want to have more than one instances of "Presse" in your program, the very least you'll need to remove ServerSocket from it. Instead, you should accept the connection from the client somewhere else, and pass the client socket to the Presse constructor:
public Presse(Socket clientSocket) throws IOException {
this.socket = clientSocket;
//Inputstream
in = socket.getInputStream();
//Outputstream
out = socket.getOutputStream();
}
Usually you want to create only one ServerSocket, and call accept on it in a loop. To allow more than one client to connect at a time, communicate with the client in a separate thread. This way the server can go and accept a new connection. Here's a skeleton example of how to use a thread pool for this:
int maxClients = 10;
ExecutorService threadPool = Executors.newFixedThreadPool(maxClients);
ServerSocket serverSocket = new ServerSocket(2000);
while (true) {
Socket clientSocket = serverSocket.accept();
threadPool.submit(() -> {
// Communicate with clientSocket, for example:
Presse p = new Presse(clientSocket);
// You'll want to have this code in a separate method
});
}

Java server program doesn't accept the input from client at second run of client

I wrote a small client server program in Java. Server creates a ServerSocket on some port and keeps listening to it. Client sends some sample info to this server.
When I run Client the first time connection is accepted by server and info is printed by server. Then Client program exits. When I run Client again, connection is accepted however, data is not printed.
Please check following code.
Server Program
package javadaemon;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class MyDaemon {
public static void main(String [] args) throws IOException {
ServerSocket ss = new ServerSocket(9879);
ss.setSoTimeout(0);
while(true) {
Socket s = ss.accept();
System.out.println("socket is connected? "+s.isConnected());
DataInputStream dis = new DataInputStream(s.getInputStream());
System.out.println("Input stream has "+dis.available()+" bytes available");
while(dis.available() > 0) {
System.out.println(dis.readByte());
}
}
}
}
Client Program
package javadaemon;
import java.io.*;
import java.net.Socket;
public class Client {
public static void main(String [] args) {
try {
System.out.println("Connecting to " + "127.0.0.1"
+ " on port " + 9879);
Socket client = new Socket("127.0.0.1", 9879);
System.out.println("Just connected to "
+ client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
for(int i=0; i<100; i++ ) {
out.writeUTF("Syn "+i);
}
} catch(IOException e) {
}
}
}
Please help me in finding why next time no data is received by server.
The reason is before server side receive data, the Client already exits, I just debug it. (Can't explain whey it works at the first time.)
Just change your code like the below, and it works.
package javadaemon;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class MyDaemon {
public static void main(String [] args) throws IOException {
ServerSocket ss = new ServerSocket(9879);
ss.setSoTimeout(0);
while(true) {
Socket s = ss.accept();
System.out.println("socket is connected? "+s.isConnected());
DataInputStream dis = new DataInputStream(s.getInputStream());
System.out.println("Input stream has "+dis.available()+" bytes available");
while(true) {
try {
System.out.println(dis.readByte());
} catch (Exception e) {
break;
}
}
}
}
}
The Client must add flush before exits,
package javadaemon;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
public static void main(String [] args) {
try {
System.out.println("Connecting to " + "127.0.0.1"
+ " on port " + 9879);
Socket client = new Socket("127.0.0.1", 9879);
System.out.println("Just connected to "
+ client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
for(int i=0; i<100; i++ ) {
out.writeUTF("Syn "+i);
}
out.flush();
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch(IOException e) {
e.printStackTrace();
}
}
}
Place this in your Client program after for loop:
out.flush();
out.close();
client.close();
You need to flush your stream in order to push the data forward and clean the stream. Also, you will need to close your client socket.
I just tested this successfully.

Object Input Stream only getting one file over network?

I have created a basic Client Server that will send image files in a specified directory over a network. The code worked last week but I came back to it today and it seems that I am only getting one file on the server side, even though the client prints out that it has sent all the image files in the directory.
It may be something in the client code but I think it is something on the server side.
Any help is greatly appreciated and if you have a more efficient solution, I am happy to change my code as necessary. My code is below:
ImageServer
package com.encima.network.server;
import java.io.*;
import java.net.*;
public class ImageServer{
ServerSocket ss;
Socket s;
ObjectOutputStream oos;
int port = 4440;
public ImageServer() throws IOException {
try {
ss = new ServerSocket(port);
System.out.println("Server started on Port: " + port);
} catch(IOException e) {
System.out.println("Serevr: Port-" + port + " not available, exiting.");
System.exit(0);
}
System.out.println("Server: Waiting for Client Connection...");
while(true) {
try {
s = ss.accept();
new ImageHandler(s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
ImageServer is = new ImageServer();
}
}
ImageHandler
package com.encima.network.server;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.net.Socket;
import javax.imageio.ImageIO;
public class ImageHandler implements Runnable {
Socket s;
int count = 0;
public ImageHandler(Socket socket) {
s = socket;
Thread t = new Thread(this);
t.start();
}
#Override
public void run() {
try {
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
FileOutputStream fos = new FileOutputStream("image" + System.nanoTime() + ".jpg");
count++;
//BufferedImage in = ImageIO.read(ois);
//ImageIO.write(in, "jpg", fos);
int ch = 0;
while(true) {
ch = ois.read();
if(ch == -1) {
break;
}
fos.write(ch);
}
fos.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Finally, the ImageClient
package com.encima.network.client;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import javax.imageio.ImageIO;
import com.encima.network.ImageFilter;
public class ImageClient {
Socket s;
String ip = "localhost";
int port = 4440;
ObjectOutputStream oos;
public ImageClient(File[] files) throws IOException, ClassNotFoundException, InterruptedException {
try {
s = new Socket(ip, port);
System.out.println("Client connected to Server via " + ip + " on port 80");
} catch (Exception e) {
System.out.println("Client: Cannot find Host: " + ip + ". Exiting.");
System.exit(0);
}
oos = new ObjectOutputStream(s.getOutputStream());
for(File f: files) {
sendFile(f);
}
oos.close();
//System.out.println("Written Image " + i + " of " + files.length);
}
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
File dir = new File("/Users/christophergwilliams/Dropbox/PhD/Projects/PhD/Year 1/GSN/images");
File[] files = dir.listFiles(new ImageFilter());
ImageClient ic = new ImageClient(files);
}
public void sendFile(File file) throws IOException {
FileInputStream fis = new FileInputStream(file);
//BufferedImage b = ImageIO.read(file);
//ImageIO.write(b, "jpg", oos);
int ch = 0;
while(true) {
ch = fis.read();
if(ch == -1) {
break;
}
oos.write(ch);
}
oos.flush();
System.out.println("Image Sent");
}
}
I am aware that it is a lot of code to read through but I do appreciate any help I can get on this!
I may be wrong but, for the sake of efficiency and network traffic, would it be beneficial to send the images as a zip from the client to the server?
Why are you using ObjectInputStream at all? You're not reading or writing any serialized objects - just raw binary data. Use whatever InputStream is provided, and read from that.
Anyway, that's not the big problem. The big problem is that you're just writing several files to one stream, with no indication of where one file is meant to finish and the next one is meant to start. How were you expecting to split the multiple files up? Options:
Use a delimiter between files (very ugly - you'd have to potentially escape any data which looked like the delimiter as you went along)
Prefix each file with its length
Send each file on a different connection
(You're also reading and writing a single byte at a time. Use the overloads of read/write which accept byte arrays.)

Categories

Resources