The byte equivalent to cut the socket link - java

Normally when I use
r = new BufferedReader(new InputStreamReader(receivedSocketConn1.getInputStream()));
then I use
int nextChar = 0;
while ((nextChar=r.read()) != -1)
{
}
Now I am going to use byte level
r = new DataInputStream(new BufferedInputStream(receivedSocketConn1.getInputStream()));
so the first byte I read is this
try {
while(true){
if (r.readByte() != 0x7E) // start byte
{
// ah oh, something went wrong!!
receivedSocketConn1.close();
return;
}
int bodyLen = r.readUnsignedShort(); // message body nature (body length)
byte serialNum1 = r.readByte();// message serial number
byte[] messageBody = new byte[20]; // message body
r.readFully(messageBody);
if (r.readByte() != 0x7E) // end byte
{
// ah oh, something went wrong!!
receivedSocketConn1.close();
return;
}
}
}
catch (SocketTimeoutException ex)
{
System.out.println("SocketTimeoutException has been caught");
ex.printStackTrace();
}
catch (IOException ex)
{
System.out.println("IOException has been caught");
ex.printStackTrace();
}
finally
{
try
{
if ( w != null )
{
w.close();
r.close();
receivedSocketConn1.close();
}
else
{
System.out.println("MyError:w is null in finally close");
}
}
}
You see it always goes into the finally block after I do the 7e, thereafter it cuts the link. I would like to keep the link for some time. But before that, I want to run a for loop for the look for the -1 in this scenario. How to I implement that?

You don't need to handle -1 in this situation.
If you read the documentation, it says:
InputStream::read()
Returns:
the next byte of data, or -1 if the end of the stream is reached.
DataInputStream::readByte()
Throws:
EOFException - if this input stream has reached the end.
IOException - the stream has been closed and the contained input stream does not support reading after close, or another I/O error occurs.
The same goes for all of the DataInputStream reading methods.
So, all you have to do is read values from the DataInputStream normally and let it throw an exception if the socket gets closed by the peer. You are already doing exactly that (EOFException extends IOException and will be caught in your catch (IOException ex) block). You are over-thinking the problem.
That being said, if reading the 0x7E byte is throwing an exception (which readByte() call is failing? Which exception is being thrown?), then you are doing something wrong. For instance, this question is based on code I gave you yesterday for another question, but the code you have shown in this question is incomplete based on the earlier code. That omission would easily cause the second if (r.readByte() != 0x7E) to evaluate as false and close the connection.
Try something more like this instead:
w = new DataOutputStream(new BufferedOutputStream(receivedSocketConn1.getOutputStream()));
r = new DataInputStream(new BufferedInputStream(receivedSocketConn1.getInputStream()));
try
{
while(true)
{
if (r.readByte() != 0x7E) // start byte
throw new RuntimeException("Incorrect start byte detected");
int messageID = r.readUnsignedShort(); // message ID
int bodyLen = r.readUnsignedShort(); // message body nature (body length)
byte[] phoneNum = new byte[6];
r.readFully(phoneNum); // device phone number
int serialNum = r.readUnsignedShort(); // message serial number
byte[] messageBody = new byte[bodyLen]; // message body
r.readFully(messageBody);
byte checkCode = r.readByte(); // check code
if (r.readByte() != 0x7E) // end byte
throw new RuntimeException("Incorrect end byte detected");
// TODO: validate checkCode if needed...
// ...
// if (checkCode is not valid)
// throw new RuntimeException("Bad checkCode value");
// process message data as needed...
}
}
catch (SocketTimeoutException ex)
{
System.out.println("SocketTimeoutException has been caught");
ex.printStackTrace();
}
catch (EOFException ex)
{
System.out.println("Socket has been closed");
}
catch (IOException ex)
{
System.out.println("IOException has been caught");
ex.printStackTrace();
}
catch (RuntimeException ex)
{
System.out.println(ex.getMessage());
ex.printStackTrace();
}
finally
{
w.close();
r.close();
receivedSocketConn1.close();
}

Related

While loop + sleep slows down PC

I am currently writing a java programm that fetches the source code from a html and parses it for a value. This works fine normally, but once I try to let it run in a while loop and refetch the data every 30 seconds my PC slows down until I stop the program manually.
while(true) {
try {
URL url = new URL("https://www.reddit.com/r/gaming/");
URLConnection urlConn = url.openConnection();
System.out.println(urlConn.getContentType()); //it returns text/html
BufferedReader in = new BufferedReader
(new InputStreamReader(urlConn.getInputStream()));
File test = new File("test");
BufferedWriter writer = new BufferedWriter(new FileWriter(test));
String text;
while ((text = in.readLine()) != null) {
writer.write (text);
}
writer.close();
in.close();
String content = new String(Files.readAllBytes(Paths.get("test")), "UTF-8");
Pattern pattern = Pattern.compile("title=(.*?)\">");
Matcher matcher = pattern.matcher(content);
if (matcher.find()) {
System.out.println(matcher.group(1));
if (Integer.valueOf((matcher.group(1))) <= 99999999) {
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(new File("alert.wav"));
clip.open(inputStream);
clip.start();
}
}
Thread.sleep(30000);
} catch (MalformedURLException f) {
f.printStackTrace();
} catch (IOException f) {
f.printStackTrace();
} catch (InterruptedException f) {
f.printStackTrace();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
Any hints on why this is happening?
Maybe I'm misunderstanding the code, but I think that Thread.sleep() will only run if you don't throw. I think you want to put it outside of the try/catch so that if you fail, you wait 30 seconds before trying again. Otherwise, if something causes a throw, you will just retry again immediately and since nothing will have really changed since the last time you tried, you will immediately throw again over and over.
Right now, your code is:
while (true) {
try {
// Do a lot of things that can throw
if(something_bad_happens) throw new Error();
/*
* This sleep will only be reached
* if we don't throw
*/
Thread.sleep(30000);
} catch (errors) {
// Deal with errors
}
}
I think you actually want this:
while (true) {
try {
// Do a lot of things that can throw
if(something_bad_happens) throw new Error();
} catch (errors) {
// Deal with errors
}
// Always sleep between attempts no matter what
Thread.sleep(30000);
}

JAVA what causes end of stream on network sockets?

From what I understand the whole point of end of stream is to tell the input stream when to stop reading data, which makes sense in file streams, but when it's an ObjectInputStream why would I want it to stop reading objects if I might send another one in the future.
In my case the ObjectInputStream throws an EOFException whenever it decides that something is causing the end of stream.
Code segment:
Sending:
public synchronized void sendCommand(CommandBase command){
try {
commandOutputStream.writeUnshared(command);
commandOutputStream.flush();
System.out.println("Sent " + command.getAction().toString());
} catch (IOException e) {
System.out.println("Failed to send " + command.getAction().toString());
try {
commandOutputStream.close();
running = false;
this.dispose();
System.out.println("Closing command output stream");
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
Receiving
while(going && tcpSender.running){
//Get action from stream
try {
System.out.println("Available bytes: " + commandInputStream.available());
Object command = ((CommandBase) commandInputStream.readObject());
System.out.println("Action received");
if (command instanceof CommandBase) {
if(((CommandBase)command).getAction().equals(ActionType.MouseAction)){
System.out.println("Mouse action");
//JOptionPane.showMessageDialog(null, "Received Mouse Action");
((MouseCommand)command).doAction(operator);
}else if(((CommandBase)command).getAction().equals(ActionType.KeyboardAction)){
System.out.println("Keyboard action");
//JOptionPane.showMessageDialog(null, "Received Keyboard Action: " + ((KeyboardCommand)command).toString());
((KeyboardCommand)command).doAction(operator);
}else if(((CommandBase)command).getAction().equals(ActionType.CheckBooleanAction)){
System.out.println("Check boolean action");
udpSender.notifyThis((CheckBooleanCommand)command);
}else{
//JOptionPane.showMessageDialog(null, "Received unknown command " + ((CommandBase)command).getAction().toString());
System.out.println("Action type is: " + ((CommandBase)command).getAction().toString());
}
}
} catch (EOFException e) {
System.out.println("EOF-Exception - end of stream reached");
e.printStackTrace();
continue;
} catch(IOException e){
System.out.println("IO-Exception - Unable to read action \n Closing socket");
try {
commandInputStream.close();
System.out.println("Closed command input stream");
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
going = false;
tcpSender.running = false;
} catch (ClassNotFoundException e) {
System.out.println("Class not found - failed to cast to Action");
e.printStackTrace();
}
}
TL;DR: How does the ObjectInputStream decide that it's the end of a stream, and what causes it?
And how can I solve this problem?
Error message:
`
java.io.EOFException at
java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown
Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
How does the ObjectInputStream decide that it's the end of a stream
It happens when ObjectInputStream attempts to read from the underlying stream, and that stream returns -1 ... which means that the end-of-stream has been reached.
and what causes it?
In this case, the most likely explanation is that the remote end (the sender) has closed its socket, or it has crashed ... which will cause the socket to close.
(It is theoretically possible that the connection has been broken, but that is only likely to happen in obscure circumstances, so lets ignore that.)
And how can I solve this problem?
You need to understand why the sending end has closed the socket. Unfortunately, we cannot tell why that is because the code you have provided is not an MCVE.

Why does my program stop running and does not return error?

I put the declaration in the while loop, and the program would not running and also does not return any error. I suspect the while loop become an infinite loop.
try
{
while (true)
{
inputStream = new ObjectInputStream (new FileInputStream (fileName));
Ship copyObject = (Ship) inputStream.readObject();
String nameCompany = copyObject.getCompanyName();
if (compName.equalsIgnoreCase(nameCompany)){
listShipName += (copyObject.getShipName() + ", ");
numberOfShip ++;
}
}
}
catch (EOFException e)
{
}
catch (Exception e)
{
e.printStackTrace();
}
But if I put the declaration of input stream out of the while loop, the program runs successfully. Can someone explain why this happens?
try
{
inputStream = new ObjectInputStream (new FileInputStream (fileName));
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
while (true)
{
Ship copyObject = (Ship) inputStream.readObject();
String nameCompany = copyObject.getCompanyName();
if (compName.equalsIgnoreCase(nameCompany)){
listShipName += (copyObject.getShipName() + ", ");
numberOfShip ++;
}
}
}
catch (EOFException e)
{
}
catch (Exception e)
{
e.printStackTrace();
}
You're reopening your file on every iteration through the loop, which means you are only ever reading the first object from the file. But you're reading the same object over and over again.
As well as opening your file only once, you really should try to detect the end of file without throwing an exception. As a matter of style, exceptions should be thrown when things go wrong, not as a matter of course.
Now I realize that in each iteration, I reopen the input stream, so the loop would not reach to the end of the file, and it becomes infinite.

Java - Stream is closed

I am running another jar with this code:
(I am updating a gui in some parts , so dont feel confused.)I get an IO Exception (Stream Closed) here:
if((line = readr.readLine()) != null){
Thats the full code:
if(!data.serverStarted()){
try{
data.updateConsole("Starting server!");
String fileDir = data.dir + File.separator + "craftbukkit.jar";
Process proc = Runtime.getRuntime().exec("java -Xmx2048M -jar "+"craftbukkit.jar"+" -o true --nojline");
data.setOutputStream(proc.getOutputStream());
InputStream is = proc.getErrorStream();
}catch(IOException ex){
ex.printStackTrace();
}
BufferedReader readr = new BufferedReader(new InputStreamReader(is));
data.setServerStarted(true);
String line;
while(data.serverStarted()){
try {
if((line = readr.readLine()) != null){
data.updateConsole(line);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
readr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}else{
data.updateConsole("You have already started your server!");
}
You have a while loop that closes readr on every pass. The next time it gets to the try block, readr is closed. Perhaps you intended to put the try/catch block around the while loop?
You are closing the reader inside the loop that reads from it. You need to close it outside of the loop:
try {
String line;
while (data.serverStarted() && ((line = readr.readLine()) != null)) {
try {
data.updateConsole(line);
} catch (IOException e) {
e.printStackTrace();
}
}
} finally {
try {
readr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I am surprised that this code even compiles.
You declare the actual InputStream is inside the try/catch at the beginning, but that makes it only visible inside that block. So whatever you give to the BufferedReader a few lines below is something else and most likely not what you think it is.
In addition your while(data.serverStarted()) does not check if the stream is still open, and later you only use a single if check (again with no check if the stream is open), so you'll only read one single line at best.
I have a feeling that you had a bad OutOfCoffeeException while writing this code. ;)

Buffereader to inputstream still having corruption

We have java socket connection application which receives data from gps devices. The problem now at times we received corrupted data and checked on the device logs everything is fine. First BufferedReader was used and suspected to be the culprit. The we moved to inpustream also still having problem. The corruption is at random and not fixed interval. Below is the snippet of codes.
public void run() {
String completeMessage="";
//BufferedReader readerBuffer = null;
InputStream is = null;
BufferedWriter writeBuffer = null;
try {
//readerBuffer = new BufferedReader(new InputStreamReader(sockConn1.getInputStream()));
is = sockConn1.getInputStream();
writeBuffer = new BufferedWriter(new OutputStreamWriter(sockConn1.getOutputStream()));
int readChar=0;
sockConn1.setSoTimeout(120000);
//dbConnection = connectionPool.getConnection();
//dbConnection.setAutoCommit(false);
int readChar
while ((readChar=is.read()) != -1)
{
System.out.println("Char value: "+(char)readChar) ;
if (readChar == '*') {
try {
//writeBuffer.write("##\r\n\r\n");
//writeBuffer.flush();
//db processing
dbConnection.commit();
}
catch (SQLException ex){
ex.printStackTrace();
try{
dbConnection.rollback();
}
catch (Exception rollback){
rollback.printStackTrace();
}
}
catch (Exception e){
e.printStackTrace(System.out);
try{
dbConnection.rollback();
}
catch (Exception rollback){
rollback.printStackTrace(System.out);
}
}
finally{
try{
if ( dbStmt != null ){
dbStmt.close();
}
}
catch(SQLException ex){
ex.printStackTrace(System.out);
}
}
completeMessage="";
}
}
}
catch (SocketTimeoutException ex){
ex.printStackTrace();
}
catch (IOException ex){
ex.printStackTrace();
}
catch (Exception ex){
ex.printStackTrace();
}
finally{
try{
if ( dbConnection != null ){
dbConnection.close();
}
}
catch(SQLException ex){
ex.printStackTrace();
}
try{
if ( writeBuffer != null ){
writeBuffer.close();
}
}
catch(IOException ex){
ex.printStackTrace(System.out);
}
}
}
There is a problem. You read/write binary data as text:
InputStream, OutputStream = binary data
Reader, Writer = text
This is bridged by:
new InputStremReader(inputStream, charEncoding)
new OutputStreamWriter(outputStream, charEncoding)
And String to byte is bridged by:
new String(bytes, charEncoding)
string.getBygtes(charEncoding)
Where charEncoding is an optional parameter, defaulting to the operation system encoding.
With UTF-8, the Unicode multi-byte encoding, you are fast into troubles if done wrong. Also other encodings have problematic bytes.
So do not use Reader/Writer.
The read() delivers an int, -1 for end-of-file, a byte value otherwise.
It seems your test with read() throws a byte away, and the subsequent read does not test for -1.
It is not clear what character encoding is used here.
When you deal with character streams then it is nearly always a good idea to explicitly provide the character encoding to en-/decode the byte stream.
In my opinion it is most likely a character encoding issue here. Use the same encoding on both sides and you won't have trouble with Reader/Writer.

Categories