I am running the following program and get the Stream Closed IO Error.
but only in the second loop. the first one works fine.
Can anybody please tell me why? (I checked that the file is existing and not empty.)
private static TimerTask perform(){
//logging on to FTP-Server
InputStream in = client.retrieveFileStream("./htdocs/pwiMain/main.txt");
InputStream pw = client.retrieveFileStream("./htdocs/pwiMain/cred_pwd.txt");
BufferedInputStream inbf = new BufferedInputStream(in);
int bytesRead;
byte[] buffer = new byte[1024];
String wholeFile = null;
String[] contents;
while((bytesRead = inbf.read(buffer)) != -1){
wholeFile = new String(buffer,0,bytesRead);
}
sentPassword = wholeFile.substring(wholeFile.indexOf("#lap"));
inbf.close();
inbf = new BufferedInputStream(pw);
while((bytesRead = inbf.read(buffer)) != -1){ // this is line72 where the error occurrs...
wholeFile = new String(buffer,0,bytesRead);
}
md5hash = wohleFile;
inbf.close();
contents = sentPassword.split("\\r\\n|\\n|\\r");
System.out.println("contents: " + contents[0] + " " + contents[1]);
//check the password
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("ioexception");
} finally {
}
return null;
}
Here is the error message:
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:159)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at java.io.FilterInputStream.read(FilterInputStream.java:107)
at com.protonmail.taylor.faebl.development.main.perform(main.java:72)
at com.protonmail.taylor.faebl.development.main.main(main.java:23)
Thanks a lot for your help :)
You evidently can't have two retrieval streams active at the same time, which isn't surprising. Just reorder your code:
private static TimerTask perform(){
try {
//logging on to FTP-Server
InputStream in = client.retrieveFileStream("./htdocs/pwiMain/main.txt");
BufferedInputStream inbf = new BufferedInputStream(in);
int bytesRead;
byte[] buffer = new byte[1024];
String wholeFile = null;
String wholeCred = null;
String[] contents;
while((bytesRead = inbf.read(buffer)) != -1){
wholeFile = new String(buffer,0,bytesRead);
}
inbf.close(); // ADDED
InputStream pw = client.retrieveFileStream("./htdocs/pwiMain/cred_pwd.txt");
BufferedInputStream pwbf = new BufferedInputStream(pw);
int pwBytesRead; // YOU DON'T NEED THIS, you could reuse the previous one
byte[] pwBuffer = new byte [1024]; // DITTO
while((pwBytesRead = pwbf.read(pwBuffer)) != -1){
wholeCred = new String(pwBuffer,0,pwBytesRead);
}
pwbf.close(); // ADDED
sentPassword = wholeFile.substring(sentPassword.indexOf("#lap"));
md5hash = wholeCred;
contents = sentPassword.split("\\r\\n|\\n|\\r");
System.out.println("contents: " + contents[0] + " " + contents[1]);
//check the password
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("ioexception");
} finally {
}
return null;
}
There's no point or advantage in the way you're doing it now, you're just wasting space, and as you've discovered it doesn't work.
Of course you will then discover that if either of the inputs exceeds one buffer it won't work, but you didn't ask about that.
Related
Question at the bottom
I'm using netty to transfer a file to another server.
I limit my file-chunks to 1024*64 bytes (64KB) because of the WebSocket protocol. The following method is a local example what will happen to the file:
public static void rechunck(File file1, File file2) {
FileInputStream is = null;
FileOutputStream os = null;
try {
byte[] buf = new byte[1024*64];
is = new FileInputStream(file1);
os = new FileOutputStream(file2);
while(is.read(buf) > 0) {
os.write(buf);
}
} catch (IOException e) {
Controller.handleException(Thread.currentThread(), e);
} finally {
try {
if(is != null && os != null) {
is.close();
os.close();
}
} catch (IOException e) {
Controller.handleException(Thread.currentThread(), e);
}
}
}
The file is loaded by the InputStream into a ByteBuffer and directly written to the OutputStream.
The content of the file cannot change while this process.
To get the md5-hashes of the file I've wrote the following method:
public static String checksum(File file) {
InputStream is = null;
try {
is = new FileInputStream(file);
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] buffer = new byte[8192];
int read = 0;
while((read = is.read(buffer)) > 0) {
digest.update(buffer, 0, read);
}
return new BigInteger(1, digest.digest()).toString(16);
} catch(IOException | NoSuchAlgorithmException e) {
Controller.handleException(Thread.currentThread(), e);
} finally {
try {
is.close();
} catch(IOException e) {
Controller.handleException(Thread.currentThread(), e);
}
}
return null;
}
So: just in theory it should return the same hash, shouldn't it? The problem is that it returns two different hashes that do not differ with every run.. file size stays the same and the content either.
When I run the method once for in: file-1, out: file-2 and again with in: file-2 and out: file-3 the hashes of file-2 and file-3 are the same! This means the method will properly change the file every time the same way.
1. 58a4a9fbe349a9e0af172f9cf3e6050a
2. 7b3f343fa1b8c4e1160add4c48322373
3. 7b3f343fa1b8c4e1160add4c48322373
Here is a little test that compares all buffers if they are equivalent. Test is positive. So there aren't any differences.
File file1 = new File("controller/templates/Example.zip");
File file2 = new File("controller/templates2/Example.zip");
try {
byte[] buf1 = new byte[1024*64];
byte[] buf2 = new byte[1024*64];
FileInputStream is1 = new FileInputStream(file1);
FileInputStream is2 = new FileInputStream(file2);
boolean run = true;
while(run) {
int read1 = is1.read(buf1), read2 = is2.read(buf2);
String result1 = Arrays.toString(buf1), result2 = Arrays.toString(buf2);
boolean test = result1.equals(result2);
System.out.println("1: " + result1);
System.out.println("2: " + result2);
System.out.println("--- TEST RESULT: " + test + " ----------------------------------------------------");
if(!(read1 > 0 && read2 > 0) || !test) run = false;
}
} catch (IOException e) {
e.printStackTrace();
}
Question: Can you help me chunking the file without changing the hash?
while(is.read(buf) > 0) {
os.write(buf);
}
The read() method with the array argument will return the number of files read from the stream. When the file doesn't end exactly as a multiple of the byte array length, this return value will be smaller than the byte array length because you reached the file end.
However your os.write(buf); call will write the whole byte array to the stream, including the remaining bytes after the file end. This means the written file gets bigger in the end, therefore the hash changed.
Interestingly you didn't make the mistake when you updated the message digest:
while((read = is.read(buffer)) > 0) {
digest.update(buffer, 0, read);
}
You just have to do the same when you "rechunk" your files.
Your rechunk method has a bug in it. Since you have a fixed buffer in there, your file is split into ByteArray-parts. but the last part of the file can be smaller than the buffer, which is why you write too many bytes in the new file. and that's why you do not have the same checksum anymore. the error can be fixed like this:
public static void rechunck(File file1, File file2) {
FileInputStream is = null;
FileOutputStream os = null;
try {
byte[] buf = new byte[1024*64];
is = new FileInputStream(file1);
os = new FileOutputStream(file2);
int length;
while((length = is.read(buf)) > 0) {
os.write(buf, 0, length);
}
} catch (IOException e) {
Controller.handleException(Thread.currentThread(), e);
} finally {
try {
if(is != null)
is.close();
if(os != null)
os.close();
} catch (IOException e) {
Controller.handleException(Thread.currentThread(), e);
}
}
}
Due to the length variable, the write method knows that until byte x of the byte array, only the file is off, then there are still old bytes in it that no longer belong to the file.
I have been writing an updater for my game.
It checks a .version file on drop box and compares it to the local .version file.
If there is any link missing from the local version of the file, it downloads the required link one by one.
This is the error that it shows
Exception in thread "Thread-9" java.lang.OutOfMemoryError: Java heap space
at com.fox.listeners.ButtonListener.readFile(ButtonListener.java:209)
at com.fox.listeners.ButtonListener.readFile(ButtonListener.java:204)
at com.fox.listeners.ButtonListener.UpdateStart(ButtonListener.java:132)
at com.fox.listeners.ButtonListener$1.run(ButtonListener.java:58)
It only shows for some computers though and not all of them this is the readFile method
private byte[] readFile(URL u) throws IOException {
return readFile(u, getFileSize(u));
}
private static byte[] readFile(URL u, int size) throws IOException {
byte[] data = new byte[size];
int index = 0, read = 0;
try {
HttpURLConnection conn = null;
conn = (HttpURLConnection) u.openConnection();
conn.addRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
InputStream is = conn.getInputStream();
progress_a = 0;
progress_b = data.length;
while(index < data.length) {
read = is.read(data, index, size-index);
index += read;
progress_a = index;
}
} catch(Exception e) {
e.printStackTrace();
}
return data;
}
private byte[] readFile(File f) {
byte[] data = null;
try {
data = new byte[(int)f.length()];
#SuppressWarnings("resource")
DataInputStream dis = new DataInputStream(new FileInputStream(f));
dis.readFully(data);
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
This is the main method that is ran
public void UpdateStart() {
System.out.println("Starting Updater..");
if(new File(cache_dir).exists() == false) {
System.out.print("Creating cache dir.. ");
while(new File(cache_dir).mkdir() == false);
System.out.println("Done");
}
try {
version_live = new Version(new URL(version_file_live));
} catch(MalformedURLException e) {
e.printStackTrace();
}
version_local = new Version(new File(version_file_local));
Version updates = version_live.differences(version_local);
System.out.println("Updated");
int i = 1;
try {
byte[] b = null, data = null;
FileOutputStream fos = null;
BufferedWriter bw = null;
for(String s : updates.files) {
if(s.equals(""))
continue;
System.out.println("Reading file "+s);
AppFrame.pbar.setString("Downloading file "+ i + " of "+updates.files.size());
if(progress_b > 0) {
s = s + " " +(progress_a * 1000L / progress_b / 10.0)+"%";
}
b = readFile(new URL(s));
progress_a = 0;
progress_b = b.length;
AppFrame.pbar.setString("Unzipping file "+ i++ +" of "+updates.files.size());
ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(b));
File f = null, parent = null;
ZipEntry entry = null;
int read = 0, entry_read = 0;
long entry_size = 0;
progress_b = 0;
while((entry = zipStream.getNextEntry()) != null)
progress_b += entry.getSize();
zipStream = new ZipInputStream(new ByteArrayInputStream(b));
while((entry = zipStream.getNextEntry()) != null) {
f = new File(cache_dir+entry.getName());
if(entry.isDirectory())
continue;
System.out.println("Making file "+f.toString());
parent = f.getParentFile();
if(parent != null && !parent.exists()) {
System.out.println("Trying to create directory "+parent.getAbsolutePath());
while(parent.mkdirs() == false);
}
entry_read = 0;
entry_size = entry.getSize();
data = new byte[1024];
fos = new FileOutputStream(f);
while(entry_read < entry_size) {
read = zipStream.read(data, 0, (int)Math.min(1024, entry_size-entry_read));
entry_read += read;
progress_a += read;
fos.write(data, 0, read);
}
fos.close();
}
bw = new BufferedWriter(new FileWriter(new File(version_file_local), true));
bw.write(s);
bw.newLine();
bw.close();
}
} catch(Exception e) {
e.printStackTrace();
return;
}
System.out.println(version_live);
System.out.println(version_local);
System.out.println(updates);
CacheUpdated = true;
if(CacheUpdated) {
AppFrame.pbar.setString("All Files are downloaded click Launch to play!");
}
}
I don't get why it is working for some of my players and then some of my other players it does not i have been trying to fix this all day and i am just so stumped at this point but this seems like its the only big issue left for me to fix.
Either increase the memory allocated to your JVM (How can I increase the JVM memory?), or make sure that the file being loaded in memory isn't gigantic (if it is, you'll need to find an alternate solution, or just read chunks of it at a time instead of loading the entire thing in memory).
Do your update in several steps. Here's some pseudo-code with Java 8. It's way shorter than what you wrote because Java has a lot of built-in tools that you re-write much less efficiently.
// Download
Path zipDestination = Paths.get(...);
try (InputStream in = source.openStream()) {
Files.copy(in, zipDestination);
}
// Unzip
try (ZipFile zipFile = new ZipFile(zipDestination.toFile())) {
for (ZipEntry e: Collections.list(zipFile.entries())) {
Path entryDestination = Paths.get(...);
Files.copy(zipFile.getInputStream(e), entryDestination);
}
}
// Done.
I have a TCP server that accepts data and saves it to a text file. It then uses that text file to create an image and sends it back to the client. Every couple of hours I will get a NullPointerException that gets thrown to every client that connects after that. I am not sure how to go about debugging this as I cannot replicate it on my own.
Does anyone have any debugging practices to help me figure out why this is becoming a problem?
The server running is running Ubuntu 12.04 i386 with 2 gigs of RAM. My initial suspicion is that something is not getting closed properly and creating issues but everything should be getting closed as far as I can tell.
ServerSocket echoServer = null;
Socket clientSocket = null;
try {
echoServer = new ServerSocket(xxx);
} catch (IOException e) {
System.out.println(e);
}
while(true)
{
InputStream is = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
int bufferSize = 0;
FileInputStream fis = null;
BufferedInputStream bis = null;
BufferedOutputStream out = null;
try {
//Receieve text file
is = null;
fos = null;
bos = null;
bufferSize = 0;
String uid = createUid();
try {
clientSocket = echoServer.accept();
clientSocket.setKeepAlive(true);
clientSocket.setSoTimeout(10000);
System.out.println("Client accepted from: " + clientSocket.getInetAddress());
} catch (IOException ex) {
System.out.println("Can't accept client connection. ");
}
try {
is = clientSocket.getInputStream();
bufferSize = clientSocket.getReceiveBufferSize();
System.out.println("Buffer size: " + bufferSize);
} catch (IOException ex) {
System.out.println("Can't get socket input stream. ");
}
try {
fos = new FileOutputStream("/my/diretory/" + uid + ".txt");
bos = new BufferedOutputStream(fos);
} catch (FileNotFoundException ex) {
System.out.println("File not found. ");
}
byte[] bytes = new byte[bufferSize];
int count;
while ((count = is.read(bytes)) > 0) {
bos.write(bytes, 0, count);
System.out.println("Receiving... " + count);
}
System.out.println("Done receiving text file");
bos.flush();
bos.close();
fos.close();
//image
String[] command = new String[3];
command[0] = "python";
command[1] = "imagecreationfile.py";
command[2] = uid;
System.out.println("Starting python script");
Boolean success = startScript(command);
if(success)
{
System.out.println("Script completed successfully");
//Send image here
String image = "/my/directory/" + uid + ".png";
File imageFile = new File(image);
long length = imageFile.length();
if (length > Integer.MAX_VALUE) {
System.out.println("File is too large.");
}
bytes = new byte[(int) length];
fis = new FileInputStream(imageFile);
bis = new BufferedInputStream(fis);
out = new BufferedOutputStream(clientSocket.getOutputStream());
count = 0;
while ((count = bis.read(bytes)) > 0) {
out.write(bytes, 0, count);
System.out.println("Writing... " + count);
}
out.flush();
out.close();
fis.close();
bis.close();
}
else
{
System.out.println("Script failed");
}
System.out.println("Closing connection");
is.close();
clientSocket.close();
} catch (Exception e) {
System.out.println(e); //This is where the exception is being caught
}
if(!clientSocket.isClosed())
{
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
if(is != null)
is.close();
if(fos != null)
fos.close();
if(bos != null)
bos.close();
if(fis != null)
fis.close();
if(bis != null)
bis.close();
if(out != null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Maybe exception was thrown in one of your try-catch scope.
And the next try-catch scope found null variables.
for example
//Receieve text file
is = null;
fos = null;
bos = null;
bufferSize = 0;
String uid = createUid();
try {
clientSocket = echoServer.accept();
clientSocket.setKeepAlive(true);
clientSocket.setSoTimeout(10000);
System.out.println("Client accepted from: " + clientSocket.getInetAddress());
} catch (IOException ex) {
System.out.println("Can't accept client connection. ");
}
try {
is = clientSocket.getInputStream();
bufferSize = clientSocket.getReceiveBufferSize();
System.out.println("Buffer size: " + bufferSize);
} catch (IOException ex) {
System.out.println("Can't get socket input stream. ");
}
if IOException was thrown in "clientSocket = echoServer.accept();" , it will print "Can't accept client connection. ".
When, "is = clientSocket.getInputStream();" executed, it will throw NullPointer because "clientSocket" was not initialized properly.
My suggestion, dont break a sequenced statement in different try-catch scope until it necessary.
Hi i have a problem with my server, everytime i call "dload" the file gets downloaded but i can't use the other commands i have because they get returned as null. Anyone who can see the problem in the code?
Server :
public class TCPServer {
public static void main(String[] args) {
ServerSocket server = null;
Socket client;
// Default port number we are going to use
int portnumber = 1234;
if (args.length >= 1) {
portnumber = Integer.parseInt(args[0]);
}
// Create Server side socket
try {
server = new ServerSocket(portnumber);
} catch (IOException ie) {
System.out.println("Cannot open socket." + ie);
System.exit(1);
}
System.out.println("ServerSocket is created " + server);
// Wait for the data from the client and reply
boolean isConnected = true;
try {
// Listens for a connection to be made to
// this socket and accepts it. The method blocks until
// a connection is made
System.out.println("Waiting for connect request...");
client = server.accept();
System.out.println("Connect request is accepted...");
String clientHost = client.getInetAddress().getHostAddress();
int clientPort = client.getPort();
System.out.println("Client host = " + clientHost
+ " Client port = " + clientPort);
// Read data from the client
while (isConnected == true) {
InputStream clientIn = client.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(
clientIn));
String msgFromClient = br.readLine();
System.out.println("Message received from client = "
+ msgFromClient);
// Send response to the client
if (msgFromClient != null
&& msgFromClient.equalsIgnoreCase("sum")) {
OutputStream clientOut = client.getOutputStream();
PrintWriter pw = new PrintWriter(clientOut, true);
Double[] list;
list = new Double[5];
String value;
int i;
try {
for (i = 0; i < 5; i++) {
pw.println("Input number in arrayslot: " + i);
value = br.readLine();
double DoubleValue = Double.parseDouble(value);
list[i] = DoubleValue;
}
if (i == 5) {
Double sum = 0.0;
for (int k = 0; k < 5; k++) {
sum = sum + list[k];
}
pw.println("Sum of array is " + sum);
}
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (msgFromClient != null
&& msgFromClient.equalsIgnoreCase("max")) {
OutputStream clientOut = client.getOutputStream();
PrintWriter pw = new PrintWriter(clientOut, true);
Double[] list;
list = new Double[5];
String value;
int i;
try {
for (i = 0; i < 5; i++) {
pw.println("Input number in arrayslot: " + i);
value = br.readLine();
double DoubleValue = Double.parseDouble(value);
list[i] = DoubleValue;
}
if (i == 5) {
Arrays.sort(list);
pw.println("Max integer in array is " + list[4]);
}
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (msgFromClient != null
&& msgFromClient.equalsIgnoreCase("time")) {
OutputStream clientOut = client.getOutputStream();
PrintWriter pw = new PrintWriter(clientOut, true);
Calendar calendar = GregorianCalendar.getInstance();
String ansMsg = "Time is:, "
+ calendar.get(Calendar.HOUR_OF_DAY) + ":"
+ calendar.get(Calendar.MINUTE);
pw.println(ansMsg);
}
if (msgFromClient != null
&& msgFromClient.equalsIgnoreCase("date")) {
OutputStream clientOut = client.getOutputStream();
PrintWriter pw = new PrintWriter(clientOut, true);
Calendar calendar = GregorianCalendar.getInstance();
String ansMsg = "Date is: " + calendar.get(Calendar.DATE)
+ "/" + calendar.get(Calendar.MONTH) + "/"
+ calendar.get(Calendar.YEAR);
;
pw.println(ansMsg);
}
if (msgFromClient != null
&& msgFromClient.equalsIgnoreCase("c2f")) {
OutputStream clientOut = client.getOutputStream();
PrintWriter pw = new PrintWriter(clientOut, true);
String celciusValue;
boolean ifRead = false;
try {
pw.println("Input celcius value");
celciusValue = br.readLine();
ifRead = true;
if (ifRead == true) {
double celcius = Double.parseDouble(celciusValue);
celcius = celcius * 9 / 5 + 32;
pw.println(celcius);
}
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (msgFromClient != null
&& msgFromClient.equalsIgnoreCase("dload")) {
OutputStream outToClient = client.getOutputStream();
if (outToClient != null) {
File myFile = new File("C:\\ftp\\pic.png");
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
try {
bis.read(mybytearray, 0, mybytearray.length);
outToClient.write(mybytearray, 0,
mybytearray.length);
outToClient.flush();
outToClient.close();
bis.close();
fis.close();
} catch (IOException ex) {
// Do exception handling
}
System.out.println("test");
}
}
if (msgFromClient != null
&& msgFromClient.equalsIgnoreCase("quit")) {
client.close();
break;
}
// if (msgFromClient != null
// && !msgFromClient.equalsIgnoreCase("bye")) {
// OutputStream clientOut = client.getOutputStream();
// PrintWriter pw = new PrintWriter(clientOut, true);
// String ansMsg = "Hello, " + msgFromClient;
// pw.println(ansMsg);
// }
// Close sockets
if (msgFromClient != null
&& msgFromClient.equalsIgnoreCase("bye")) {
server.close();
client.close();
break;
}
msgFromClient = null;
}
} catch (IOException ie) {
}
}
}
Client:
import java.io.*;
import java.net.*;
public class TCPClient {
public static void main(String args[]) {
boolean isConnected = true;
Socket client = null;
int portnumber = 1234; // Default port number we are going to use
if (args.length >= 1) {
portnumber = Integer.parseInt(args[0]);
}
try {
String msg = "";
// Create a client socket
client = new Socket("127.0.0.1", 1234);
System.out.println("Client socket is created " + client);
// Create an output stream of the client socket
OutputStream clientOut = client.getOutputStream();
PrintWriter pw = new PrintWriter(clientOut, true);
// Create an input stream of the client socket
InputStream clientIn = client.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(
clientIn));
// Create BufferedReader for a standard input
BufferedReader stdIn = new BufferedReader(new InputStreamReader(
System.in));
while (isConnected == true) {
System.out
.println("Commands: \n1. TIME\n2. DATE\n3. C2F\n4. MAX\n5. SUM\n6. DLOAD\n7. QUIT");
// Read data from standard input device and write it
// to the output stream of the client socket.
msg = stdIn.readLine().trim();
pw.println(msg);
// Read data from the input stream of the client socket.
if (msg.equalsIgnoreCase("dload")) {
byte[] aByte = new byte[1];
int bytesRead;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (clientIn != null) {
try {
FileOutputStream fos = new FileOutputStream("C:\\ftp\\pic.png");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = clientIn.read(aByte, 0, aByte.length);
do {
baos.write(aByte, 0, bytesRead);
bytesRead = clientIn.read(aByte);
} while (bytesRead != -1);
bos.write(baos.toByteArray());
bos.flush();
bos.close();
System.out.println("File is successfully downloaded to your selected directory"+ "\n" +"*-----------------*"+ "\n" );
} catch (IOException ex) {
System.out.println("Couldn't dowload the selected file, ERROR CODE "+ex);
}
}
}else{
System.out.println("Message returned from the server = "
+ br.readLine());
}
if (msg.equalsIgnoreCase("bye")) {
pw.close();
br.close();
break;
}
}
} catch (Exception e) {
}
}
}
debugged your code and have two hints:
1)
don't surpress your exceptions. handle them! first step would to print your stacktrace and this question on SO wouldn't ever be opened ;-) debug your code!
2)
outToClient.flush();
outToClient.close(); //is closing the socket implicitly
bis.close();
fis.close();
so in your second call the socket on server-side will already be closed.
first thing:
if (args.length >= 1) {
portnumber = Integer.parseInt(args[0]);
}
This can throw a NumberFormatException, and because args[0] is passed by the user you should handle this.
reading the code also this gave me a problem:
double DoubleValue = Double.parseDouble(value); // LINE 104
Throwing a NumberFormatException when I give c2f as command to the server. You definitively need to handle this exception anywhere in your code and give proper answer to the client, something like:
try{
double DoubleValue = Double.parseDouble(value);
}catch(NumberFormatException e){
// TELL THE CLIENT "ops, the number you inserted is not a valid double numer
}
(in short example, starting from this you have to enlarge the code)
while (isConnected == true) {
I cannot see it! why not use this?
while (isConnected) {
if (msgFromClient != null && msgFromClient.equalsIgnoreCase("sum")){
can be:
if("sum".equalsIgnoreCase(msgFromClient)){
in this case you have no problem with the NullPointerException. (if msgFromClient is null the statement is false).
By the way, date and time command are working fine for me. Check the others.
To fix dload i think you have to delete the line:
outToClient.close();
(EDIT: sorry to maxhax for the same answr, didn't see your answer while writing this)
This question already has answers here:
java.io.StreamCorruptedException: invalid stream header: 54657374
(2 answers)
Closed 4 years ago.
im writen a client-server app, and now i´m facing a problem that I dont know how to solve:
This is the client:
try
{
Socket socket = new Socket(ip, port);
ObjectOutputStream ooos = new ObjectOutputStream(socket
.getOutputStream());
SendMessage message = new SendMessage();
message.numDoc = value.numDoc;
message.docFreq = value.docFreq;
message.queryTerms = query;
message.startIndex = startIndex;
message.count = count;
message.multiple = false;
message.ips = null;
message.ports = null;
message.value = true;
message.docFreq = value.docFreq;
message.numDoc = value.numDoc;
ooos.writeObject(message);
ObjectInputStream ois = new ObjectInputStream(socket
.getInputStream());
ComConstants mensajeRecibido;
Object mensajeAux;
String mensa = null;
byte[] by = null;
do
{
mensajeAux = ois.readObject();
if (mensajeAux instanceof ComConstants)
{
System.out.println("Thread by Thread has Search Results");
String test;
ByteArrayOutputStream testo = new ByteArrayOutputStream();
mensajeRecibido = (ComConstants) mensajeAux;
byte[] wag;
testo.write(
mensajeRecibido.fileContent, 0,
mensajeRecibido.okBytes);
wag = testo.toByteArray();
if (by == null) {
by = wag;
}
else {
int size = wag.length;
System.arraycopy(wag, 0, by, 0, size);
}
} else
{
System.err.println("Mensaje no esperado "
+ mensajeAux.getClass().getName());
break;
}
} while (!mensajeRecibido.lastMessage);
//ByteArrayInputStream bs = new ByteArrayInputStream(by.toByteArray()); // bytes es el byte[]
ByteArrayInputStream bs = new ByteArrayInputStream(by);
ObjectInputStream is = new ObjectInputStream(bs);
QueryWithResult[] unObjetoSerializable = (QueryWithResult[])is.readObject();
is.close();
//AQUI TOCARIA METER EL QUICKSORT
XmlConverter xce = new XmlConverter(unObjetoSerializable, startIndex, count);
String serializedd = xce.runConverter();
tempFinal = serializedd;
ois.close();
socket.close();
} catch (Exception e)
{
e.printStackTrace();
}
i++;
}
And this is the sender:
try
{
QueryWithResult[] outputLine;
Operations op = new Operations();
boolean enviadoUltimo=false;
ComConstants mensaje = new ComConstants();
mensaje.queryTerms = query;
outputLine = op.processInput(query, value);
//String c = new String();
//c = outputLine.toString();
//StringBuffer swa = sw.getBuffer();
ByteArrayOutputStream bs= new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream (bs);
os.writeObject(outputLine);
os.close();
byte[] mybytearray = bs.toByteArray();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(mybytearray);
BufferedInputStream bis = new BufferedInputStream(byteArrayInputStream);
int readed = bis.read(mensaje.fileContent,0,4000);
while (readed > -1)
{
mensaje.okBytes = readed;
if (readed < ComConstants.MAX_LENGTH)
{
mensaje.lastMessage = true;
enviadoUltimo=true;
}
else
mensaje.lastMessage = false;
oos.writeObject(mensaje);
if (mensaje.lastMessage)
break;
mensaje = new ComConstants();
mensaje.queryTerms = query;
readed = bis.read(mensaje.fileContent);
}
if (enviadoUltimo==false)
{
mensaje.lastMessage=true;
mensaje.okBytes=0;
oos.writeObject(mensaje);
}
oos.close();
} catch (Exception e)
{
e.printStackTrace();
}
}
And this is the error log:
Thread by Thread has Search Results
java.io.StreamCorruptedException: invalid stream header: 20646520
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at org.tockit.comunication.ServerThread.enviaFicheroMultiple(ServerThread.java:747)
at org.tockit.comunication.ServerThread.run(ServerThread.java:129)
at java.lang.Thread.run(Unknown Source)
Where at org.tockit.comunication.ServerThread.enviaFicheroMultiple(ServerThread.java:747) is this line ObjectInputStream is = new ObjectInputStream(bs); on the 1st code just after while (!mensajeRecibido.lastMessage);
Any ideas?
The value 20646520 is in ASCII #A.
ObjectInput/OutputStreams use a "magic" value at the beginning of the stream, to indicate it complies to the special serialization of the objects. (I think this was 0xCAFEBABE, but I'm not sure)
This means in your situation that something has already read the stream before the ObjectInputStream has the chance to read the magic, or that the stream it reads is not producted by an ObjectOutputStream;
You assign the variable by to wig (or append), which is a byte array which is not generated by an ObjectOutputStream, as far as I can tell, since it uses mensajeRecipido.fileContent. I presume mensajeRecipido.fileContent is the content of an actual file. In this running instance is not of the same format as an ObjectOutputStream, and that's why you get the stream header exception.