can't instantiate ObjectInputStream to read input from user - java

I can't add a ObjectInputStream to read input from the user, it always blocks at that point. This code works fine if I remove the ObjectInputStream in the Server that is supposed to read input from user and then send hardcoded String instead. What is happening behind the scenes? I'am aware that when a ObjectOutputStream is created it sends a header and when a ObjectInputStream is created it reads that header. Do I need to flush something in System before I try to instantiate oOISUser?
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public Server() {
ServerSocket oSS = null;
Socket oS = null;
ObjectOutputStream oOOS = null; // to write to socket
ObjectInputStream oOIS = null; // to read from socket
ObjectInputStream oOISUser = null; // to read input from user
try {
oSS = new ServerSocket(1025);
oS = oSS.accept();
oOOS = new ObjectOutputStream(oS.getOutputStream());
oOIS = new ObjectInputStream(oS.getInputStream());
oOISUser = new ObjectInputStream(System.in);`// doesn't get past this
String sToSend = (String) oOISUser.readObject();
System.out.println("server says: " + sToSend);
oOOS.writeObject(sToSend);
oOOS.flush();
System.out.println("server receives: " + (String) oOIS.readObject());
} catch (IOException e) {
System.out.println(e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
} finally {
try {
if (oSS != null) oSS.close();
if (oS != null) oS.close();
if (oOOS != null) oOOS.close();
if (oOIS != null) oOIS.close();
if (oOISUser != null) oOISUser.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
public static void main(String[] args) {
Server s = new Server();
}
}
This is the code for the Client:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class Client {
public Client() {
Socket oS = null;
ObjectOutputStream oOOS = null;
ObjectInputStream oOIS = null;
try {
oS = new Socket("127.0.0.1", 1025);
oOOS = new ObjectOutputStream(oS.getOutputStream());
oOIS = new ObjectInputStream(oS.getInputStream());
System.out.println("client receives: " + (String) oOIS.readObject());
String sToSend = "hello from client";
System.out.println("client says: " + sToSend);
oOOS.writeObject(sToSend);
oOOS.flush();
} catch (IOException e) {
System.out.println(e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
} finally {
try {
if (oS != null) oS.close();
if (oOOS != null) oOOS.close();
if (oOIS != null) oOIS.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
public static void main(String[] args) {
Client c = new Client();
}
}

new ObjectInputStream(System.in)
You said it yourself in the question:
when a ObjectInputStream is created it reads that header
So you're effectively waiting for the user to enter an ObjectInputStream header in the console. That has a very very tiny chance to happen (unless a file is piped to System.in). It just makes very little sense to read serialized Java objects from System.in. The user can't possibly type valid serialized Java objets in the console. He/She can type text, though. So use a Reader or a Scanner.

Related

Android - How to work with complex object via socket

I'm kind of new to Android and I have a task to open a TCP socket and listen to a specific port.
A client application is supposed to send me 2 images and a string that are related to each other so instead of sending each data alone we thought about putting all data in a json object and send this object.
My question is, how do I parse this json into saving 2 images and a string?
So this json is supposed to be like this:
data
{
FileName: "some string",
Image1: "Image encoded with encode base64",
Image2: "Image encoded with encode base64"
}
I'm using an AsyncTask so here is the code where I get the socket data:
public class DataRecord
{
String Image1;
String Image2;
String FileName;
}
protected DataRecord doInBackground(Socket... sockets) {
DataRecord dataRecord = null;
if (isExternalStorageWritable() && sockets.length > 0) {
Socket socket = sockets[0];
dataRecord = socket.getOutputStream(); // how to extract the data from the socket into this object ???
File file = new File(Environment.getExternalStorageDirectory(), dataRecord.FileName);
byte[] bytes = new byte[(int) file.length()];
BufferedInputStream inputStream;
try {
inputStream = new BufferedInputStream(new FileInputStream(file));
inputStream.read(bytes, 0, bytes.length);
OutputStream outputStream = dataRecord.Image1;
outputStream.write(bytes, 0, bytes.length);
outputStream.flush();
socket.close();
}
catch (Exception e) { }
finally {
try {
socket.close();
} catch (IOException e) { }
}
}
return dataRecord;
}
And I need to get it from the socket object and extract an object from it to save the 2 images to the SD card and extract the string to the UI.
I know this question probably have more than one answer, but still posting an answer is a good idea.
So, I found this link here A Simple Java TCP Server and TCP Client which helped me getting started with my solution.
I've also used Gson to parse my JSON string using this nice tutorial: Android JSON Parsing with Gson Tutorial.
Finally, my code looks like this:
ServerSockerThread.java - this is the java class for the listening server which waits for incoming files:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerSocketThread extends Thread {
static final int SocketServerPORT = 6789;
ServerSocket serverSocket;
#Override
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SocketServerPORT);
while (true) {
socket = serverSocket.accept();
new FileSaveThread().execute(socket);
}
}
catch (IOException e) { }
finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) { }
}
}
}
protected void onDestroy() {
if (serverSocket != null) {
try {
serverSocket.close();
}
catch (IOException e) { }
}
}
}
FileSaveThread.java - this is the java class that is being called by the above server class for each incoming file:
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Base64;
import com.google.gson.Gson;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.Socket;
public class FileSaveThread extends AsyncTask<Socket, Void, DataRecord> {
#Override
protected void onPostExecute(DataRecord dataRecord) {
super.onPostExecute(dataRecord);
}
#Override
protected DataRecord doInBackground(Socket... sockets) {
DataRecord dataRecord = null;
if (isExternalStorageWritable() && sockets.length > 0) {
Socket socket = sockets[0];
try {
Gson gson = new Gson();
Reader reader = new InputStreamReader(socket.getInputStream());
SocketObject socketObject = gson.fromJson(reader, SocketObject.class);
SaveFileToSDCard(socketObject.Image1, "Image1.png");
SaveFileToSDCard(socketObject.Image2, "Image2.png");
SaveFileToSDCard(socketObject.Image3, "Image3.png");
dataRecord = new DataRecord(socketObject.Name);
}
catch (Exception e) { }
finally {
try {
socket.close();
} catch (IOException e) { }
}
}
return dataRecord;
}
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
private void SaveFileToSDCard(String base64String, String fileName) throws IOException {
byte[] decodedString = Base64.decode(base64String.getBytes(), android.util.Base64.DEFAULT);
File file = new File(Environment.getExternalStorageDirectory(), fileName);
FileOutputStream fileOutputStream = new FileOutputStream(file, false);
fileOutputStream.write(decodedString);
fileOutputStream.close();
fileOutputStream.flush();
}
}

Persistent client-server socket connection in Java

I'm trying to establish a two-way communication in Java. For that I created a simple client-server program (I'm not even sure if that's the right approach because both of them are considered client!). My requirement is that once the two program are connected, they should maintain the connection, and be able to send messages once in a while. However, currently my socket terminates once it had sent the data (client's main method has been executed).
How can I maintain the connection, so to make it persistent?
P.S: Is there any ways to make it work in an asynchronous way that might be more suitable for my requirements (I don't want the server always looping inside a while)?
Client:
package test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class EchoClient2 {
String serverHostname = new String("127.0.0.1");
BufferedReader stdIn;
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
public void open(){
System.out.println("Attemping to connect to host " + serverHostname
+ " on port 9999.");
try {
echoSocket = new Socket(serverHostname, 9999);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + serverHostname);
} catch (IOException e) {
System.err.println("Couldn't get I/O for " + "the connection to: "
+ serverHostname);
}
}
public void send(String s){
out.println(s);
}
public String receive(){
String result = "";
try {
result = in.readLine();
System.out.println("client received: "+result);
if(result==null)
return "0";
} catch (IOException e) {
}
return result;
}
public static void main(String[] args) {
EchoClient2 ec = new EchoClient2();
ec.open();
ec.send("1");
ec.receive();
}
}
Server:
package test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class EchoServer extends Thread {
protected Socket clientSocket;
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(9999);
System.out.println("Connection Socket Created");
try {
while (true) {
System.out.println("Waiting for Connection");
new EchoServer(serverSocket.accept());
}
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
} catch (IOException e) {
System.err.println("Could not listen on port: 9999.");
System.exit(1);
} finally {
try {
serverSocket.close();
} catch (IOException e) {
System.err.println("Could not close port: 9999.");
System.exit(1);
}
}
}
private EchoServer(Socket clientSoc) {
clientSocket = clientSoc;
start();
}
public void run() {
System.out.println("New Communication Thread Started");
try {
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),
true);
BufferedReader in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("Server received: " + inputLine);
out.println(inputLine);
if (inputLine.equals("Bye."))
break;
}
// out.close();
// in.close();
// clientSocket.close();
} catch (IOException e) {
System.err.println("Problem with Communication Server");
System.exit(1);
}
}
}
First of all sorry for the late answer. I am also stuck in this java socket programming. I also want to open a socket and keep it open for communication between client and server. And after searching and reading many books and articles I found the easiest solution. You can use android life cycles for your work in
Open the socket on onStart method
protected void onStart() {
super.onStart();
new Thread(new Runnable() {
#Override
public void run() {
try {
client = new Socket(ip,Integer.valueOf(port) );
client.setKeepAlive(true);
dataInputStream = new DataInputStream(client.getInputStream());
// readdata=readdata+" "+dataInputStream.readUTF();
readdata=dataInputStream.readUTF();
}
catch (Exception e){
e.printStackTrace();
}
}
}).start();
}
and close the socket on onStop method
protected void onStop() {
super.onStop();
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}

Application Hangs over the socket, Unable to read client data at server side

I am trying to implement a client server socket connection where i am passing commands like ls/pwd over the GUI and I use an url(localhost) to establish the server connection at the port. Although i am able to establish a connection with client ,the code does not proceed beyond the Client Connection accepted state. I.e. it does not read the input at the server end which was sent by the client over the socket. Below are my three classes, Mainserver, ClientHandler(this handles the thread connections for the server)and the Client.
This is the Client Action button performed code:
private void jButton1ActionPerformed(java.awt.event.ActionEventevt) {
command = jTextField1.getText();
String url = jTextField3.getText();
try {
System.out.println("Before socket connection");
Socket socket = new Socket(url, 9002);
System.out.println("After socket connection");
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("After Buffered readers");
System.out.println("After getting streams");
if (socket != null) {
try {
int x = Integer.parseInt(command);
flag = 1;
} catch (Exception e) {
flag = 0;
}
if (flag == 0) {
String[] cmd = {"/bin/sh", "-c", command};
System.out.println("the value of command in GUI class is " + Arrays.toString(cmd));
try {
String commd = Arrays.toString(cmd);
System.out.println(commd);
out.write(commd);
input = in.readLine();
}
catch (IOException ex1)
{
Logger.getLogger(TestGUI.class.getName()).log(Level.SEVERE, null, ex1);
}
jTextField2.setText(input.toString());
}
}
}//try end of the first one
catch (IOException ex) {
Logger.getLogger(TestGUI.class.getName()).log(Level.SEVERE, null, ex);
}
The server class:
public class ServerMain {
public static void main(String[] args) throws IOException, InterruptedException {
int number, temp;
try {
ServerSocket serverSocket = new ServerSocket(9002);
System.out.println("server has been started in the server");
System.out.println("Server is waiting connection at" + InetAddress.getLocalHost().getCanonicalHostName() + "port" + serverSocket.getLocalPort());
while (true) {
Socket socket = serverSocket.accept();
System.out.println("Client Connection Accepted");
//pass on handling on this client to a thread
(new ClientHandler(socket)).start();
}
} catch (Exception e) {
System.err.println("Server already in use");
System.exit(-1);
}
}
}
The client Handler for the Server:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* #author ameerah
*/
public class ClientHandler extends Thread {
private static int BUFSIZE = 1024;
private StringBuffer result;
ServerSocket serverSocket;
String serverText;
StringBuffer output = new StringBuffer();
private Object serversocket;
public Socket getSock() {
return sock;
}
public void setSock(Socket sock) {
this.sock = sock;
}
Socket sock;
public ClientHandler(Socket sock) {
this.sock = sock;
}
#Override
public void run() {
PrintWriter outWriter = null;
try {
BufferedReader myInput = new BufferedReader(new InputStreamReader(sock.getInputStream()));
outWriter = new PrintWriter(sock.getOutputStream());
System.out.println(
"before accepting the command in server");
String inputLine;
while ((inputLine = myInput.readLine()) != null) //String command = myInput.readLine();
{
System.out.println(inputLine);
String result = "";
try {
result = executeCommand(inputLine);
} catch (IOException ex) {
Logger.getLogger(ClientHandler.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
Logger.getLogger(ClientHandler.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(result);
outWriter.write(result);
}
} catch (IOException ex) {
Logger.getLogger(ClientHandler.class.getName()).log(Level.SEVERE, null, ex);
} finally {
outWriter.close();
}
}
public String executeCommand(String cmd)
throws IOException, InterruptedException {
try {
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
BufferedReader reader
= new BufferedReader(new InputStreamReader(p.getInputStream()));
System.out.println("Inside the execute method");
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
return output.toString();
}
}
I have been at it for some time, and tried using different streams such as ObjectInputStream, ObjectOutputStream, but the code hangs each time. I cannot see at this point where Im going wrong :( I've searched in several forums but I do not still get an idea where Im going wrong here.Would appreciate any help.!
Best Regards
It was the readLine() which was expecting '\n' at the end. Therefore once i appended '\n' at the end and added out.flush() it was able to read and not keep hanging waiting for more inputs, and now the application is working.
Thank you very much for your helpful suggestions. The out.flush() advice proved to be very helpful.
Few tips to isolate the problem.
Check the value of command and catch Exception stack trace.
After out.write(commd); : add one more line out.flush(); After flush, server will get the data from client. Same is the case with outWriter. flush() should be called on outWriter after writing the data.
You are looking for an end of line to end your input loop but you are using write.
Change your send data statements to use println.
Client:
out.println(commd);
Server:
outWriter.println(result);

Stream Corrupted Exception

I'm writing a client/server program using sockets. The client first sends the file name and the server reads the file from hard disk and sends back to the client through socket. Finally the client writes the content into a file. When I run the code a java.io.StreamCorruptedException: invalid stream header error is returned.
Client code:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ClientSocket {
private static final String SERVER_IP = "10.8.17.218";
private static final int SERVER_PORT = 5000;
String fileName;
String ip;
Socket socket;
Message msg=null,message=null;
ObjectInputStream in = null;
ObjectOutputStream out = null;
ObjectOutputStream toFile=null;
File destFile;
public ClientSocket(String ipi,String fname){
fileName = fname;
ip=ipi;
msg=new Message(fileName);
destFile=new File("C:\\DestinationDirectory",fileName);
try {
socket = new Socket(SERVER_IP, SERVER_PORT);
System.out.println("Connected to server!");
} catch (Exception ex) {
System.out.println("Error connecting to server: " + ex.getMessage());
}
while(true){
try {
if (out == null) {
out = new ObjectOutputStream(socket.getOutputStream());
}
out.writeObject(msg);
out.flush();
//get the reply from the server
if (in == null) {
in = new ObjectInputStream(socket.getInputStream());
}
message = (Message) in.readObject();
//System.out.println("Server said: " + message.getMessage());
} catch (Exception ex) {
System.out.println("Error: " + ex);
}
try {
toFile = new ObjectOutputStream(new FileOutputStream(destFile));
toFile.writeObject(message);
System.out.println(message.getMessage());
} catch (IOException ex) {
Logger.getLogger(ClientSocket.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void main(String[] args) {
ClientSocket cs= new ClientSocket("10.8.17.218","build.sql");
}
}
Server code:
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerFile {
private static final int PORT = 5000;
public static void main(String[] args) {
ServerSocket serverSocket = null;
Message message=null,toOut=null;
try {
//Creates a new server socket with the given port number
serverSocket = new ServerSocket(PORT);
} catch (IOException ex) {
System.out.println("Error occured while creating the server socket");
return;
}
Socket socket = null;
try {
//Waits untill a connection is made, and returns that socket
socket = serverSocket.accept();
} catch (IOException ex) {
System.out.println("Error occured while accepting the socket");
return;
}
//Now we have established the a connection with the client
System.out.println("Connection created, client IP: " + socket.getInetAddress());
ObjectInputStream in = null,fromFile=null;
ObjectOutputStream out = null,tempOut=null;
File sourceFile;
FileInputStream from=null;
BufferedInputStream bis;
String name=null;
while(true){
try {
if (in == null) {
in = new ObjectInputStream(socket.getInputStream());
}
message= (Message) in.readObject();
System.out.println("Client said: " + message.getMessage());
name=message.getMessage();
sourceFile=new File("D:\\temp\\",name);
name="D:\\temp\\"+name;
System.out.println(name);
from=new FileInputStream("D:/temp/build.sql");
bis=new BufferedInputStream(from);
fromFile=new ObjectInputStream(bis);
toOut=(Message) fromFile.readObject();
//Send a reply to the client
if (out == null) {
out = new ObjectOutputStream(socket.getOutputStream());
}
out.writeObject(toOut);
out.flush();
} catch (Exception ex) {
System.out.println("Error: " + ex);
}
}
}
}
You're creating a new ObjectInputStream per transaction in the server, yet you're using a single ObjectOutputStream in the client. You should use exactly one of each at both ends for the life of the socket.

java.io.StreamCorruptedException: invalid type code: AC client server-Can't find multiple instance of ObjectOutputStream [duplicate]

This question already has an answer here:
StreamCorruptedException: invalid type code: AC
(1 answer)
Closed 5 years ago.
I am having the same issue as describe in:
https://stackoverflow.com/questions/17196588/java-io-streamcorruptedexception-invalid-type-code-ac-client-server
However, I do not see how I am creating multiple ObjectOutputStream. I am sure the OP received the correct answer and I am sure i am SOMEHOW creating multiple instances, but I don't see how.
public class Node {
public static void main(String[] args)
{
File file = new File("hotwords.txt");
AppendableObjectOutputStream oos = null;
OutputStream outStream = null;
long fileSize = file.length();
ArrayList<String> hotwords = new ArrayList<String>();
try
{
BufferedReader br = new BufferedReader(new FileReader(file));
String CurrentLine;
while (( CurrentLine = br.readLine()) != null) {
hotwords.add(CurrentLine);
System.out.println("HOTWORD: " + CurrentLine);
}
br.close();
}
catch(Exception e) {
e.printStackTrace();
System.exit(0);
}
Socket s = null;
try{
s = new Socket("server", 8189);
PrintWriter writer = new PrintWriter(s.getOutputStream(), true);
writer.println("NODE");
outStream = s.getOutputStream();
oos = new AppendableObjectOutputStream(outStream);
oos.flush();
}
catch(Exception e)
{
e.printStackTrace();
System.exit(1);
}
try{
String os = System.getProperty("os.name").toLowerCase();
File logs;
if(os.matches("windows"))
{
logs = new File(".../logs");
System.out.println("Opening windows directory");
}
else
{
logs = new File("...logs");
System.out.println("Opening linux directory");
}
for( File f : logs.listFiles() )
{
if(f.getName().matches("machine.log"))
//if(f.getName().matches(".*log$"))
{
System.out.println("FOUND LOG " + f);
Runnable r = new FileHandler(s, oos, f, hotwords, file, fileSize);
Thread t = new Thread(r);
t.start();
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
FileHandler.java /* This will create a thread for a log file to continuously read through it*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
public class FileHandler implements Runnable {
Socket c;
File file;
ArrayList<String> hotwords;
long hws;
File hwf;
AppendableObjectOutputStream oos;
public FileHandler(Socket conn, AppendableObjectOutputStream oos , File f, ArrayList<String> h, File hotwordFile, long hotwordSize)
{
c=conn;
file=f;
hotwords = h;
hws = hotwordSize;
hwf=hotwordFile;
this.oos = oos;
}
public void run()
{
System.out.println("FILEHANDLER:THREAD STARTED");
String sCurrentLine;
BufferedReader br = null;
try {
br = new BufferedReader( new FileReader(file) );
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
HashMap<String, LinkedHashSet<String> > temp = new HashMap<String, LinkedHashSet<String> >();
temp.put("FILEMON", new LinkedHashSet<String>() );
try {
//OutputStream outStream = c.getOutputStream();
//AppendableObjectOutputStream oos = new AppendableObjectOutputStream(outStream); moved to cache node so everyone share same output stream
boolean test = true;
while(test)
{
if(hwf.length() != hws)
{
hws = hwf.length();
hotwords.clear();
try
{
BufferedReader hbr = new BufferedReader(new FileReader(file));
String CurrentLine;
while (( CurrentLine = hbr.readLine()) != null) {
hotwords.add(CurrentLine);
System.out.println("HOTWORD: " + CurrentLine);
}
hbr.close();
}
catch(Exception e) {
e.printStackTrace();
System.exit(0);
}
}
while((sCurrentLine = br.readLine()) != null)
{
System.out.println(sCurrentLine);
for( String h : hotwords)
{
if( sCurrentLine.matches(h) )
{
System.out.println("FILEHANDLER:FOUND MATCHING LINE " + sCurrentLine);
temp.get("FILEMON").add(file.getName() + ": " + sCurrentLine);
break;
}
}
}
if(!temp.get("FILEMON").isEmpty())
{
if(c.isConnected())
{ oos.writeObject(temp); oos.reset(); }
System.out.println("NODE:PRINTED OBJECT: Size of FILEMON " + temp.get("FILEMON").size() + " with id: " + temp.toString());
temp.get("FILEMON").clear();
System.out.print("NODE:SIZE OF FILEMON AFTER CLEAR: " + temp.get("FILEMON").size());
}
}
br.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
Hub.java /*This is a hub that runs on a seperate machine which recieves data from nodes*/
public class CacheMonitorHub {
public static void main(String[] args)
{
Map<Socket, AppendableObjectOutputStream> clients = Collections.synchronizedMap(new HashMap<Socket, AppendableObjectOutputStream>());
try
{
ServerSocket s = new ServerSocket(8189);
while(true)
{
Socket incoming = s.accept();
System.out.println("Spawning " + incoming);
Runnable r = new ConnectionHandler(incoming, clients);
Thread t = new Thread(r);
t.start();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Handler.java /*Lastly, this is responsible for publishing messages to clients*/
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class ConnectionHandler implements Runnable {
Map<Socket, AppendableObjectOutputStream> Sockets;
Socket incoming;
public ConnectionHandler(Socket socket, Map<Socket, AppendableObjectOutputStream> others)
{
incoming = socket;
Sockets = others;
}
public void run()
{
InputStream inStream = null;
OutputStream outStream = null;
ObjectInputStream ois= null;
AppendableObjectOutputStream oos =null;
try{
inStream = incoming.getInputStream();
outStream = incoming.getOutputStream();
}
catch(IOException e)
{
e.printStackTrace();
}
System.out.println("Creating Scanner..");
Scanner in = new Scanner(inStream);
//PrintWriter out = new PrintWriter(outStream, true /* autoFlush */);
String clientOrNode = "";
clientOrNode = in.nextLine();
System.out.println("HUB: " + clientOrNode);
if(clientOrNode.equals("CLIENT"))
{
System.out.println("HUB:FOUND A CLIENT!");
/*
AppendableObjectOutputStream oos = null;
try{
oos = new AppendableObjectOutputStream(outStream);
}
catch(IOException e)
{
e.printStackTrace();
System.exit(0);
}
*/
try{
oos = new AppendableObjectOutputStream(outStream);
}
catch(IOException e)
{
e.printStackTrace();
}
Sockets.put(incoming, oos);
}
else if ( clientOrNode.equals("NODE") )
{
try {
ois = new ObjectInputStream(inStream);
}
catch(IOException e){
e.printStackTrace();
}
System.out.println("HUB:FOUND A NODE!");
System.out.println("HUB:ABOUT TO ENTER WHILE");
while(1==1)
{
try{
System.out.println("HUB:IN WHILE LOOP ABOUT TO READ OBJECT");
HashMap<String, LinkedHashSet<String>> temp = null;
try {
temp = (HashMap<String, LinkedHashSet<String>>) ois.readObject();
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("HUB:OBJECT RECIEVED " + temp.toString());
for(Socket s : Sockets.keySet())
{
System.out.println("HUB:WRITING OBJECT NOW TO " + s.toString());
try {
Sockets.get(s).writeObject(temp);
Sockets.get(s).reset();
}
catch(Exception e)
{
Sockets.remove(s);
}
}
System.out.println("PAST FOR LOOP!!");
}
catch(Exception e)
{
e.printStackTrace();
}
try {
Thread.sleep(200);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
}
AppendableObjectOutputStream /*Just tried adding this as seen on suggestion from other post but not helping*/
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.IOException;
public class AppendableObjectOutputStream extends ObjectOutputStream {
public AppendableObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
#Override
protected void writeStreamHeader() throws IOException {
// do not write a header, but reset:
// this line added after another question
// showed a problem with the original
reset();
}
}
Any ideas as to why I am getting java.io.StreamCorruptedException: invalid type code: AC?
Unless the FileHandler.run()method is synchronized, or there is internal synchronization within it, neither of which is true, I don't see how you can possibly expect this to work. You're writing to the same ObjectOutputStream from multiple threads: you're going to get interleaving of data. Anything could happen at the receiver.
NB testing isConnected() doesn't accomplish anything useful. You did connect the Socket, when you created it, and isConnected() will continue to tell you so, even after you close it. It doesn't for example tell you whether the connection is still alive.

Categories