I have a thread which sends UDP packets at fixed intervals. After a while I am calling interrupt() from another thread and I am expecting the sender thread to completely finish after that. Most of the time, the sender thread does finish after receiving the interrupt. In some rare cases, however, the sender thread does not. Can you help me spot the mistake in my thread code?
try {
DatagramSocket socket = null;
Timber.d("Initialize the sender...");
while (!Thread.currentThread().isInterrupted()) {
try {
Timber.d("Sending UDP broadcasts...");
socket = new DatagramSocket();
while (!Thread.currentThread().isInterrupted()) {
String s = "hello";
byte[] buffer = s.getBytes();
DatagramPacket packet = new DatagramPacket(
buffer, buffer.length,
mBroadcastAddress, PORT);
try {
if (BuildConfig.DEBUG)
Timber.d("[" + new DateTime().toLocalTime() + "] " +
"Send UDP packet");
socket.send(packet);
} catch (IOException ioe) {
Timber.d(ioe, "IOException");
}
Thread.sleep(TIMEOUT_SLEEP);
}
} catch (SocketException se) {
Timber.d(se, "Socket exception");
break;
} finally {
if (socket != null)
socket.close();
socket = null;
}
}
} catch (InterruptedException ie) {
Timber.d("The sender thread received interrupt request");
}
Timber.d("Finish the sender...");
I think that the problem is here:
} catch (IOException ioe) {
Timber.d(ioe, "IOException");
}
The problem is that one of the subtypes of IOException is ... InterruptedIOException. And when that exception is thrown (in response to an interrupt), the thread's interrupted flag is cleared. Now it is "pretty unlikely" that this code is going to be interrupted in the middle of a send call. But if it does, then you will effectively "eat" an interrupt.
I think you should change the above to:
} catch (InterruptedIOException ioe) {
Thread.currentThread().interrupt();
} catch (IOException ioe) {
Timber.d(ioe, "IOException");
}
In addition, if are going to test the interrupt flag later on, you are also "eating" it when you catch InterruptedException at the end of the snippet, and you should set it again ... as above.
As I can see, in a certain portion of your code, you are swallowing the interruptedException.Restore the interrupt after catching interruptedException,do not swallow it.
This is how you restore the interrupt
Thread.currentThread().interrupt();
Related
How to reopen socket connection of the client, if sever was stopped then ran again?
P.S. Maybe it is not necessary to view all the code, just look through the "wait" loop in the Client code.
Socket socket = new Socket(ipAddress, serverPort);
while (true)
{
line = keyboard.readLine();
try
{
out.writeUTF(line);
out.flush();
line = in.readUTF();
}
catch (SocketException e)
{
while (socket.isClosed())
{
System.out.println("no signal");
try
{
Thread.sleep(200);
}
catch (InterruptedException e1)
{
e1.printStackTrace();
}
//Here I need some code for reconnection
}
}
System.out.println(line);
}
If socket closed connection client should get exception on read/write operation. If client wants to re-new the connection, just implement it. You catch block should create new socket exactly as you are doing in the beginning of your code snippet.
Something like the following:
while(true) {
Socket socket = new Socket(ipAddress, serverPort);
try {
while(true) {
// read/write operations
}
} catch (SocketException e) {
continue; // this will return you to creation of new socket
}
}
So, i started working on my multiplayer game today and i run into a serious problem with delay in my networking. When i test things on one machine using localhost, theres no noticable delay. But when i tried running client on my laptop and server on PC im experiencing about 2-3 sec delay.
Basically what im doing is:
Server:
Is running two threads, one that listens for packets on a port and when recieves a packet with input, he updates the gamestate accordingly. The second thread takes the gamestate from the first and every 10ms he sends it to the client.
Client:
Also two threads, one recieves the gamestate and the second sends packets with keyboard input every 10ms.
Im seding datagrampackets with bytearray which came from serialized class (Both have size about 100 bytes)
Send code:
ServerPacket testPacket = new ServerPacket(player.getX(),player.getY());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = null;
try
{
out = new ObjectOutputStream(bos);
out.writeObject(testPacket);
byte[] Bytes = bos.toByteArray();
DatagramPacket packet = new DatagramPacket(Bytes,Bytes.length,ip,port);
socket.send(packet);
//System.out.println("SERVER:SentUpdate");
}
catch (IOException ex)
{
System.out.println(ex.getMessage());
}
finally
{
try
{
if (out != null)
{
out.close();
}
}
catch (IOException ex)
{
System.out.println(ex.getMessage());
}
try
{
bos.close();
}
catch (IOException ex)
{
System.out.println(ex.getMessage());
}
}
Recieve code:
byte[] data = new byte[packetLength];
DatagramPacket packet = new DatagramPacket(data, data.length);
try
{
socket.receive(packet);
}
catch (IOException ex)
{
System.out.println(ex.getMessage());
}
ByteArrayInputStream bis = new ByteArrayInputStream(packet.getData());
ObjectInput in = null;
try
{
in = new ObjectInputStream(bis);
ServerPacket res = (ServerPacket)in.readObject();
return res;
}
catch (IOException ex)
{
System.out.println(ex.getMessage());
}
catch (ClassNotFoundException ex)
{
System.out.println(ex.getMessage());
}
finally
{
try
{
bis.close();
} catch (IOException ex)
{
System.out.println(ex.getMessage());
}
try
{
if (in != null)
{
in.close();
}
}
catch (IOException ex)
{
System.out.println(ex.getMessage());
}
}
Any ides why is it so slow? Or anything i should know about udp networking.
How are you achieving such high frequency with your two threads (10ms)? Are you sure they are running at such high frequency? Why use different threads for receiving and sending - that will take longer than sending after receiving on the same thread. Of course you have to accommodate for some latency over the Internet games often have to tolerate up to 200ms between each peer - in client server that could be up to 400ms.
import javax.comm.*;
import java.io.*;
import java.util.*;
public class Sms {
public synchronized static String main1(String arr) {
char cntrlZ=(char)26;
InputStream input = null;
OutputStream output = null;
SerialPort serialPort = null;
try {
CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier("COM3");
serialPort = (SerialPort) portId.open("SimpleReadApp1", 2000);
//System.out.println("sdiosdfdsf");
String f=null;int n;
input = serialPort.getInputStream();
output = serialPort.getOutputStream();
Thread readThread;
serialPort.notifyOnDataAvailable(true);
try {
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {}
output.write(("ATZ\r\natH\r\n+CMGW: 0\r\n+CMGW: 1\r\n").getBytes());
output.flush();Thread.sleep(200);
output.write(("ath0\r\n").getBytes());
output.flush();Thread.sleep(200);
output.write(("AT+CMGF=1\r\n").getBytes());
output.flush();Thread.sleep(200);
output.write(("AT+CMGS=\"09629993650\"\r\n+CMGW: 20\r\n").getBytes());
output.write(("hellooopssss445 545inoo you there?").getBytes());
output.write(("\032").getBytes());
output.flush();
Thread.sleep(2000);
byte[] readBuffer = new byte[120];
try {
while (input.available() > 0) {
int numBytes = input.read(readBuffer);
}
input.close();
output.close();
serialPort.removeEventListener();
serialPort.sendBreak(1000);
serialPort.getInputStream().close();
serialPort.getOutputStream().close();
if (serialPort!=null)
System.out.print("Port is not null!!!");
//serialPort.closeport();
if (serialPort!=null)
System.out.print("Port is not null!!!");
System.out.print(new String(readBuffer));
return(new String(readBuffer));
} catch (IOException e) {}
output.flush();
} catch (NoSuchPortException e) {
System.out.println("Exception in Adding Listener" + e);
} catch (PortInUseException e) {
System.out.println("Exception in Adding Listener" + e);
} catch (IOException e) {
System.out.println("Exception in Adding Listener" + e);
}
catch (InterruptedException e) {
System.out.println("Exception in Adding Listener" + e);
}
return ("fault");
}
public static void main(String[] arg) {
char ii[]=main1("").toCharArray();
for(int j=0;j<ii.length;j++)
{
if((ii[j]=='O')&&(ii[j+1]=='K'))
System.out.println("GOT");
}
}
}
When I compile and execute this program, message is not sent until I remove my Mobile from USB.And if I don't remove my Mobile and run the same program, Its shows Busy and CMI ERROR : 503.
And second message is never sent (when program is compiled again).Moreover Port is never closed as you can see in the program.
What can be done in this code? Please don't provide me some other program like SMSLIB rather improve/edit this code.
I'm trying this for about 3 days , still negative results.
Please help me.I want to send Bulk SMS without disconnecting the mobile again and again.
You must never use sleep like that; you must read and parse the response given by the modem. Sleeping like that is only marginally better then not waiting at all (which I address in this answer). See this answer for how to read and parse the response you get back.
BTW, an AT command should be terminated with only \r and not \r\n (unless you have changed S3, and you should not do that), see V.250 for more details on that and AT commands in general (e.g. if you have not already read that specification it is highly recommended).
Im creating a server client program where client sends certain information to the server and get according response from the server.
For continuously listening from multiple clients I have a thread in server which continuously listens client request. whenever a request is received I start another thread and send that socket to run and start listening for other clients request.
here is the code for continuously listening
while(true){
//serverListener is a ServerSocket object
clientSocket = serverListener.accept();//Waiting for any client request
//New thread started when request is received from any client
Thread thread =new Thread(new serverThread(clientSocket), "ClientThread");
thread.start();
}
Now my problem is that how can i stop the server. I know one alternative of using a boo lean variable in while loop and then changing the value, but the problem is when where thread is in waiting to get any connection at that time changing value of the boolean variable will also not stop the server.
Is there any way to solve this problem.
Typically the serverListener (which I assume is actually a ServerSocket or something) is closed by another thread. This will generate a java.net.SocketException in accept() which will terminate the loop and the thread.
final ServerSocket serverSocket = new ServerSocket(8000);
new Thread(new Runnable() {
public void run() {
while (true) {
try {
serverSocket.accept();
} catch (IOException e) {
return;
}
}
}
}).start();
Thread.sleep(10000);
serverSocket.close();
ServerSocket#setSoTimeout() may of your interest, that will abandon accept if a timeout was reached. Be aware of catch the SocketTimeoutException.
volatile boolean finishFlag = false;
while(true){
clientSocket = serverListener.accept();//Waiting for any client request
if ( finishFlag )
break;
//New thread started when request is received from any client
Thread thread =new Thread(new serverThread(clientSocket), "ClientThread");
thread.start();
}
EDIT:
for interrupting listener, you should stop this thread from outside, and then accept( ) will throws IOException
try {
while (true) {
Socket connection = server.accept( );
try {
// any work here
connection.close( );
}
catch (IOException ex) {
// maybe the client broke the connection early.
}
finally {
// Guarantee that sockets are closed when complete.
try {
if (connection != null) connection.close( );
}
catch (IOException ex) {}
}
}
catch (IOException ex) {
System.err.println(ex);
}
I have three classes, the client, the server and the handler (which is going to handle the server connections) as I show below:
// The Client
public void sendSomePackage() {
try {
socket = new Socket("localhost", 54321);
sos = socket.getOutputStream();
oos = new ObjectOutputStream(sockOutput);
} catch (IOException e) {
e.printStackTrace(System.err);
return;
}
// About to start reading/writing to/from socket
try {
Package package = new Package(100);
oos.writeObject(pacote);
} catch (IOException e) {
e.printStackTrace(System.err);
}
try {
Thread.sleep(50);
} catch (Exception e) {
e.printStackTrace();
}
// Done reading/writing to/from socket, closing socket.
try {
sock.close();
} catch (IOException e) {
System.err.println("Exception closing socket.");
e.printStackTrace(System.err);
}
//Exiting
}
Now the server class:
// The Server - with a method that just wait for connections
public void waitForConnections() {
while (true) {
try {
socket = serverSocket.accept();
// Server:Accepted new socket, creating new handler for it
SimpleHandler handler = new SimpleHandler(socket);
handler.start();
// Server:Finished with socket, waiting for next connection
}
catch (IOException e){
e.printStackTrace(System.err);
}
}
}
My handler, which just handle the server connections:
#Override
public void run() {
//Handler: Handler run() starting
while (true) {
try {
package = (Package) ois.readObject();
if (pacote != null) {
System.out.println("Package received " + pacote.getSourceid());
}
} catch (Exception e) {
e.printStackTrace(System.err);
break;
}
}
try {
// SimpleHandler:Closing socket
sock.close();
ois.close();
} catch (Exception e) {
// Handler: Exception while closing socket, e=" + e);
e.printStackTrace(System.err);
}
}
The idea is the client send some 'package' object to my server which is going to keep running receiving the 'package' object any time.
The connection works fine, but in the end of the program an exception is launched, this is the one:
Package received 100
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)
at br.ufscar.socket.SimpleHandler.run(SimpleHandler.java:45)
at java.lang.Thread.run(Unknown Source)
I already search for something on Google but nothing so far.
Any idea ?
This is working exactly as you want it to (probably). It reads the 100 then goes through the loop again (while(true) never stops looping until a break statement) and throws an exception because no more data has been sent and it goes to the catch statement and prints the error before exiting your while loop.
EOFException ist an IOException that indicates the end of an stream.
Here we say that if there aren't any more bytes to read then we should break out of the while loop before trying to read the object, etc.
while (true) {
if (ois.read() == -1) break;
//...rest of the code
}
Ok, this is how object streams work and the solution that works everywhere.
Object stream data is preceded by a 4 byte 'magical' sequence AC ED 00 05. An ObjectInputStream will peek for this data at construction time rather than before the first read. And that's logical: one wants to be sure it is a proper stream before being too far in an application. The sequence is buffered by the ObjectOutputStream at construction time so that it is pushed on the stream at the first write.
This method gives rise to complexities in buffered situations or transferring via sockets.
Fortunately there is a just as simple as effective solution to all these problems:
Flush the ObjectOutputStream immediately after construction!
ObjectOutputStream myStream = new ObjectOutputStream ( anotherStream );
myStream.flush();