Im using this code:
final int LOCK_PORT= 54321;
ServerSocket ss = new ServerSocket(LOCK_PORT);
The thing is that in the same port you cannot listen to 2 different applications (teachers theory).
This code was implemented into an application and the same instance ran more than 1 time. The objective is that the same instance is not suposed to run more than 1 time in the same port. However this isnt working and it does run...
// Edited, more code...
public VentanaPropiedades() {
initFirst();
initComponents(); //graphic components of Matisse
}
private void initFirst() {
loadProperties(); //just internal values of the program, nothing to do
activateInstance();
}
private void activateInstance() throws Exception {
try {
final int LOCK_PORT= 54321;
ServerSocket ss = new ServerSocket(LOCK_PORT);
} catch (Exception e) {
System.out.println(e);
throw e;
}
}
private void killProgram() {
setVisible(false);
dispose();
System.exit(0);
}
private void validateInstance() {
try {
activateInstance();
} catch (Exception ex) {
killProgram();
}
}
--------------------------Supposed Solution---------------------------
The error catched when the 2nd instance DOES NOT RUN is this one:
java.net.BindException: Address already in use: JVM_Bind
However, this error not always happens and you can run more than 1 instance of the same program.
It doesn't work. You should get a BindException the second time you try to create the
socket. See if you accidentally catch it somewhere or if the port actually is different
or something similar.
The ServerSocket must be declared outside the method, right after main:
public class VentanaPropiedades extends javax.swing.JFrame {
ServerSocket ss = null;
// ... more code
}
And the activation method should use the reference:
private void activateInstance() throws Exception {
try {
final int LOCK_PORT= 54321;
ss = new ServerSocket(LOCK_PORT); // note the missing "ServerSocket" before ss
} catch (Exception e) {
System.out.println(e);
throw e;
}
}
The problem is that if you create the variable ServerSocket inside a method, the garbage collector will clean it once the method is done. If the variable is declared above, the garbage collector wont collect and clean it because the declared variable will stay instantiated but with NO reference.
Related
This question already exists:
how to close a thread out of multiple instantiations
Closed 6 years ago.
I am making a skype like program. I have an "accept" thread and multiple User threads for each call. I store the accept thread in an arraylist every time a call is started. What I need to do is when there is less than two people in the call is interrupt the accept thread that goes with the user thread that send the command. To do this when an accept thread is created I log the index number and pass it on to all of the user threads so when it needs to send the interrupt command it just gets the thread from the arraylist using the index number. But when I send it nothing happens. Could someone tell me why this is? Thank you in advance!!!
Accept Thread
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class accept extends Thread { // Chat and Voice Server User Accept
private ServerSocket TextChat;
private Socket sText;
private int TextPort;
private int index;
boolean running = true;
accept(int ChatPort) {
TextPort = ChatPort;
chat.threads.add(this);
index = chat.threads.indexOf(Thread.currentThread());
try {
TextChat = new ServerSocket(ChatPort);
} catch (IOException e) {
System.out.println("Cant create server on port "+ ChatPort);
try {
TextChat.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public void run() {
while(running == true) {
try {
sText = TextChat.accept();
System.out.println(sText+" Joined the chat");
new TextChat(sText, TextPort, index).start();
} catch (IOException e) {
System.out.println("Server on port "+TextChat+" Can't Accept");
try {
TextChat.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
System.out.println("Server on port "+TextChat+" Is Shutting Down");
try {
TextChat.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
public void setRunning(boolean run) {
running = run;
}
}
User Thread
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
public class TextChat extends Thread {
private ObjectOutputStream out;
private ObjectInputStream in;
private Socket s;
private String msg;
private Boolean running = true;
private int port;
private String name;
private int threadIndex;
TextChat(Socket sText, int TextPort, int index) {
s = sText;
port = TextPort;
threadIndex = index;
try {
out = new ObjectOutputStream(s.getOutputStream());
if(port <= 65511) {
chat.users1.add(out);
}else {
chat.users2.add(out);
}
in = new ObjectInputStream(s.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while(running == true) {
try {
msg = in.readObject().toString();
String[] part = msg.split("/");
if(part[0].equals("MYNAME")) {
name = part[1];
System.out.println("NAME ADDED "+name);
}
if(!msg.equals(null)) {
if(port <= 65511) {
for(ObjectOutputStream o : chat.users1) {
o.writeObject(name+": "+msg);
}
}else {
for(ObjectOutputStream o : chat.users2) {
o.writeObject(name+": "+msg);
}
}
}
} catch (ClassNotFoundException | IOException e) {
System.out.println(name+" Disconneted from chat");
if(port <= 65511) {
chat.users1.remove(out);
}else {
chat.users2.remove(out);
}
if(chat.users1.size() < 2) {
System.out.println("Chat server on port "+port+" is shutting down due to not enough people in call");
chat.threads.get(threadIndex).running = false;
running = false;
}
}
}
}
}
When you interrupt a thread, all it does is set a flag. This flag is monitored by some operations, but unless you are using one of these operations, nothing happens.
If you have a thread which is blocked on IO, the most effective why to unblock the thread is to close() the stream or socket to kill it. I would also set a flag e.g. boolean closed so you can detect that any IOException thrown was the cause of you closing the socket, rather than an error.
EDIT: Some suggestions.
always uses TitleCase for class names.
avoid mutable static fields wherever possible. In this case, I don't believe you need any.
always pass shared state, and make sure it's thread safe is used from multiple threads.
Don't extend Thread rather implement a Runnable and wrap it with a Thread
You only need one server port in this cases, unless you are implementing this as a peer-to-peer service, but that doesn't appear to be the case.
no need to write verbose expressions like while (running == true) when while (running) will do.
if you have a boolean running which is shared between threads make sure it is volatile.
DON'T catch an Exception and pretend it didn't happen. You are better off throws IOException on the constructor instead of creating a dead object.
Wrap each client in an object, and only register this object, not the thread which runs the object. As you have noted, holding the Thread isn't very useful.
Don't use a wrapper like Boolean when you don't expect a null value. Use a boolean which can't be null instead.
I suggest using flags which are false by default. Instead of running used closed. This makes it easier to know what the default/normal value of the variable is.
don't hard code ports like this in code, you should pass a flag or an id to say how it should behave.
Only use Object Stream for passing general objects. For passing text you can use a Writer/Reader or Data Stream which is simpler.
You don't need to check for null for a value which cannot be null e.g. msg.equals(null) can''t every return true.
Use the spell checker in your IDE Disconneted should be Disconnected
I wouldn't disconnect when you have 1 as someone might be about to join.
In following code i am trying to start and stop the server on button using java applet.Start works good using thread but i want to stop the server on button. I have used volatile variable.Still i am not getting the server stop..
here is code:
public class TCPServer extends Thread {
public static final int SERVERPORT = 8002;
private boolean running = false;
public volatile boolean stop = false;
public Socket client = null;
public static void main(String[] args) {
ServerBoard frame = new ServerBoard();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public void run() {
super.run();
running = true;
try {
System.out.println("Server Has Started........ \n Waiting for client........");
ServerSocket serverSocket = new ServerSocket(SERVERPORT);
try {
while (!stop && running) {
client = serverSocket.accept();
System.out.println("Connection Accepted......");
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String usercmnd = in.readLine();
if (usercmnd != null) {
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec(usercmnd);
}
}
if (stop) {
serverSocket.close();
client.close();
System.out.println("Server Has Stopped");
System.exit(0);
}
} catch (Exception e) {
System.out.println("Error");
e.printStackTrace();
}
} catch (Exception e) {
System.out.println("Error");
e.printStackTrace();
}
}
public void requestStop() {
stop = true;
}
}
But whenever i click the stop button which will stop the server.Its not showing any output on console as i expected by the code.Its also not showing any error
here is code of stop button
stopServer = new JButton("Stop");
stopServer.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
stopServer.setEnabled(false);
startServer.setEnabled(true);
mServer = new TCPServer();
mServer.requestStop();
}
});
It doesn't stop because you create a new instance before stopping it and you don't even start it first while you are supposed to call requestStop() on your current instance of TCPServer.
// Here you create a new instance instead of using the existing one
mServer = new TCPServer();
mServer.requestStop();
in your ActionListener implementation for the stop button, you are accessing a different instance of TCPServer (as you are creating a new one). So you set the value "Stop" to a second object. It has no impact on the first instance that was created with the start button.
Try to instanciate the TCServer outside of your implementation of the action listener for both buttons and use that single instance for both.
Due to https://docs.oracle.com/javase/7/docs/api/java/net/ServerSocket.html#accept()
ServerSocket::accept is a blocking method, so stop variable can only be checked between successful connections.
You can either set a ServerSocket timeout using ServerSocket::setSoTimeout (and catch SocketTimeoutException), or interrupt Server thread and catch InterruptedException.
Both exceptions will be throwed from ServerSocket::accept.
Note, that thread interruption is highly preferred over timeouts and repeatly exception catching.
Try this:
public void requestStop() {
stop = true;
interrupt();
}
However, in this case, we can not guarantee, that already processing logic will successfully shutdown.
Also, you try invoke requestStop for new instance of TCPServer, instead already existing.
your code client = serverSocket.accept(); is blocking. So once you clicked "stopServer" button, you requested the stop, but it will be acted upon only once a client sends a next request to the server. What you need to do is to run your logic in your method run() in a separate thread and catch there InterruptedException and ClosedByInterruptException and clean up and return there. On your stopButton click you will invoke interrupt() method on your Thread. Read about it in here
I am working on a Java UDP application. There is a thread in the application whose only job is to listen to a server on a specific port.
I wrote the application under the mistaken assumption that the server I am listening to will always be up; this, however, was a bad assumption.
If my application starts after the server is running, then everything works fine. If my application starts before the server is up, or if the server is restarted while my application is running, my application breaks.
MainClass.java
public class MainClass {
public static void main(String[] args){
ListeningClass myListeningClass = new ListeningClass();
Thread listenerThread = new Thread(myListeningClass);
listenerThread.setName("My Listening Thread");
listenerThread.start();
}
}
ListeningClass.java
public class ListeningClass implements Runnable {
private volatile boolean run = true;
private byte[] receiveBuffer;
private int receiveBufferSize;
private DatagramSocket myDatagramSocket;
private DatagramPacket myDatagramPacket;
#Override
public void run(){
try {
myDatagramSocket = new DatagramSocket(null);
InetSocketAddress myInetSocketAddress = new InetSocketAddress(15347);
myDatagramSocket.bind(myInetSocketAddress);
receiveBuffer = new byte[2047];
myDatagramPacket = new DatagramPacket(receiveBuffer, 2047);
while(run){
myDatagramSocket.receive(myDatagramPacket);
byte[] data = myDatagramPacket.getData();
receiveBufferSize = myDatagramPacket.getLength();
// process the data received here
}
} catch (SocketException se){
// do stuff
} catch (IOException ioe){
// do stuff
}
}
public boolean isRun(){
return run;
}
public void setRun(boolean run){
this.run = run;
}
}
Like I said, if my application starts after the server is running, everything works perfectly, just as expected. However, if my application starts before the server is running, then nothing works. Obviously, is is because the thread tries to open the connection once, and if it fails, then it never tries again.
I moved the DatagramSocket open code to within the while block but that wasn't pretty. I got a bunch of "port already bound" errors.
So, how can I reconstruct this so that it works properly?
It's not really a concurrency question. You just need to check the exceptions thrown on receive and handle appropriately. In this case, rebind the socket. See the docs for receive.
For example:
...
while(run) {
try {
myDatagramSocket.receive(myDatagramPacket);
byte[] data = myDatagramPacket.getData();
receiveBufferSize = myDatagramPacket.getLength();
// process the data received here
} catch (IOException ioe) {
// Perhaps use PortUnreachableException but not guaranteed
rebind(myDatagramSocket, myInetSocketAddress);
}
}
private void rebind(DatagramSocket s, InetSocketAddress addr) {
s.bind(addr);
}
I think that should be enough. the point is, you only want to rebind if your receive indicates there's an I/O problem with the server. You're binding for each receive if you place the bind in the loop - which is ok in your happy-path situation.
The important things to note here are the precise points in which the program fails and the type of exception that you're given.
Presumably it fails on line myDatagramSocket.receive(myDatagramPacket);, but double check with the stacktrace on your exception. The second thing to check is the type of exception. Is it a SocketException or a subclass of SocketException? Is there a specific error code? Try to be as specific as possible.
At this point, you should surround the section of code that fails in its own try catch within the while loop. You want to be able to say that should it fail, your thread will sleep and try again after a hiatus (to not bombard the server with requests). And to simply things further, I would section the code in its own method, so you would expect something like:
public class ListeningClass implements Runnable {
private static final int MAX_RETRIES = 30;
private static final int RETRY_SLEEPTIME = 30000;
private volatile boolean run = true;
private InetSocketAddress myInetSocketAddress;
#Override
public void run(){
try {
DatagramSocket myDatagramSocket = new DatagramSocket(null);
myInetSocketAddress = new InetSocketAddress(15347);
myDatagramSocket.bind(myInetSocketAddress);
byte[] receiveBuffer = new byte[2047];
DatagramPacket myDatagramPacket = new DatagramPacket(receiveBuffer, 2047);
awaitRequests(myDatagramSocket, myDatagramPacket)
} catch (SocketException se){
// do stuff
} catch (IOException ioe){
// do stuff
}
}
private void awaitRequests(DatagramSocket myDatagramSocket, DatagramPacket myDatagramPacket) throws SocketException, IOException {
int maxRetries = MAX_RETRIES;
while(run){
try {
myDatagramSocket.receive(myDatagramPacket);
byte[] data = myDatagramPacket.getData();
// Packet received correctly, reset retry attempts
maxRetries = MAX_RETRIES;
process(myDatagramPacket);
} catch (SocketException e) {
maxRetries--;
// Good place to write to log of some kind
if(maxRetries == 0) {
throw e;
}
Thread.currentThread().sleep(RETRY_SLEEPTIME);
// Lets attempt to restablish the connection
reconnect(myDatagramSocket);
}
}
}
private void process(DatagramPacket myDatagramPacket) {
int receiveBufferSize = myDatagramPacket.getLength();
// process the data received here
}
private void reconnect(DatagramSocket myDatagramSocket) {
myDatagramSocket.bind(myInetSocketAddress);
}
public boolean isRun(){
return run;
}
public void setRun(boolean run){
this.run = run;
}
}
Note a couple things. I only caught SocketException because I am assuming the type of exception that you're getting is a SocketException. If you're getting an IOException of some kind, then you should check that. Better still if you're specifying the subtype of that exception. The reason is this: you don't want to blanket handle all errors, but only those pertaining to the server being down. If the program lacks authentication to open the socket, you would want to fail immediately, not continually retry.
The second thing is that I've separated the processing of the packet in its own method, because I think that's the proper thing to do in these cases.
I'm facing this issue working with a ServerSocket inside one of my bundles, let's just call it: FooBundle.
This FooBundle has, among others, a SocketListener.java class. This class is a Thread and to make a little overview of it, I'll paste some pseudocode:
public class SocketListener implements Runnable{
ServerSocket providerSocket;
Socket connection = null;
private boolean closeIt = false;
public void run() {
try {
//Create the server socket
providerSocket = new ServerSocket(41000, 10);
} catch (IOException e1) {
//catching the exception....
}
while(!closeIt){
try{
connection = providerSocket.accept();
in = new Scanner(new InputStreamReader(onnection.getInputStream()));
while(in.hasNext() !=false)
message = message + " "+in.next();
// bla bla bla...
} catch (IOException e) {
//bla bla...
}
finally{
try{
if (message.equalsIgnoreCase("bye"))
providerSocket.close();
closeIt = true;
}
catch(IOException ioException){
//........
}
}
As you can see, it's a simple thread that waits for a connection until the message it receives from one of the SocketClients is "bye".
This is the problem I'm facing right now: When the Bundle is stopped, I do need to restart the entire OSGi framework : If I try to restart the bundle, a java.net.BindException message is thrown: "Address already in use". So, I stopped the bundle but the socket hasn't been closed.
In OSGi, you need to take care of what the stop() method inside the Activator must include, but I just can't pass any reference of an anonymous thread to the Activator.
Imagine that this is my class diagram inside the bundle:
**FooBundle**
|__FooBundleActivator
|__FooImpl
|__SocketListener (thread)
The SocketListener thread is called from the FooImpl class as an anonymous thread.
My question is: Is there any appropiate method to have such control of anonymous threads and specifically in my case, of non-closing socket ports, inside the OSGi paradigm?
Thanks in advance.
If your bundle is told to stop then assume the guy doing the stopping knows what he is doing. Yes, your protocol expects the 'bye' but shit happens, any protocol that has problems with these things is too fragile for the real world. In general, all your tasks in OSGi should have a life cycle. So this would be my code (using DS instead of activators).
#Component
public class ProtocolServer extends Thread {
volatile ServerSocket server;
volatile Socket connection;
public ProtocolServer() {
super("Protocol Server on 4100"); // to identify the thread
}
#Activate void activate() {
setDaemon(true);
start();
}
#Deactivate void deactivate() {
interrupt();
// best effort close (even if null)
try { server.close(); } catch(Exception e) {}
try { connection.close(); } catch(Exception e) {}
join(10000); // waits 10 secs until thread exits
}
public void run() {
// loop for active component
while( !isInterrupted() )
try {
doServer();
} catch( Exception e) {
log(e);
// bad error, accept failed or bind failed
// or server socket was closed. If we should remain
// active, sleep to prevent overloading the
// system by trying too often, so sleep
if ( !isInterrupted() )
try { Thread.sleep(5000); } catch(Exception e) {}
}
}
private void doServer() throws Exception {
server = new ServerSocket(4100)
try {
while( !isInterrupted() )
doConnection(server);
} finally {
server.close();
}
}
private void doConnection(ServerSocket server) throws Exception {
connection = server.accept();
try {
doMessages(connection);
// the pseudo code exits here, but that seems
// kind of weird? If desired, interrupt
// this object, this will exit the thread
} catch( Exception e) {
log(e); // the connection failed, is not uncommon
} finally {
connection.close();
connection = null;
}
}
private void doMessages(Socket connection) {
MyScanner s = new MyScanner(socket);
String msg;
while( !isInterrupted() && !"bye".equals( msg=s.getMessage()))
process(msg);
}
}
One important design consideration in OSGi is that the components keep working even if there are failures. In a network you often have transient errors that go away on their own. Even if they don't it is desirable that the server keeps on trying while you fix the problem. Your pseudo code would be a nightmare in practice since it would disappear on any error. Any system with multiple such components tends to becomes quickly unstable.
One thing that also surprised me is that you only support one connection at a time. In general it is better to not limit this and handle the messages in their own thread. In that case, you must ensure that each created handler for a connection is also closed appropriately.
Instantiate the ServerSocket outside (probably in the Activator) and pass it to the SocketListener via a constructor. You can call serverSocket.stop() in the stop function of the Activator than.
In case you call ServerSocket.stop() a SocketException will be thrown that is a subclass of IOException. Please think of handling IOException in the while iteration in the way that it will stop executing the iteration for sure.
You need to close that listening socket regardless of the message before exiting the thread function. Then what should really make a difference for you is calling setReuseAddress(true) on that socket to allow binding the port while old connection hangs in the timeout state.
And, please please please, use better indentation technique in your code ...
Is it correct to create a thread and call its start() method inside a class' constructor as done here?
public class Server implements Runnable {
private ServerSocket server;
public Server(int port) {
try {
//Opens a new server
server = new ServerSocket(port);
} catch (IOException ioe) {
ioe.printStackTrace();
}
new Thread(this, "Server").start();
}
#Override
public void run() {
}
}
IMHO, do not do this. You're allowing the this reference to escape during construction.
Granted, your code isnt doing it but what if your code looked like this:
public Server(int port)
{
new Thread(this, "Server").start();
try
{
//Opens a new server
server = new ServerSocket(port);
}
catch (IOException ioe){ ioe.printStackTrace(); }
}
#Override
public void run(){
if(server == null)throw new NullPointerException();// this may happen
}
}
The server reference may be null even though no exception occurs. This is because the Thread will use the created runnable and invoke the run method even if the constructor of your class hasn't finished.
Server s = new Server();
Thread t = new Thread(s, "Server").start();
is more testable. It allows you to create an instance of Server and unit test its methods without spawning a thread.
A couple more good reasons to split the Thread.start() from the constructor:
If you ever want to use some other framework/system to run the threads, such as a java.util.concurrent.Executor, you may do so.
If you ever want to interrupt the thread, you need a reference to it. Creating the Thread in a separate line of code makes this somewhat more routine / idiomatic. e.g.
Thread rememberMe = new Thread(server).start();
In your original code, Server could have a field to remember myThread, but it didn't.
public class Server implements Runnable
{
private ServerSocket server;
/**
* Because the constructor is private, the only way to instantiate a Server is through
* the static factory method.
* If there are any instantiation problems, the static factory method will fail in
* first line, before it is put into a thread.
* It will be put into a thread before being released.
**/
public static Server startServer ( int port )
{
Server server = new Server ( port ) ;
new Thread ( server , "Server" ) . start ( ) ;
return server ;
}
private Server(int port)
{
try
{
//Opens a new server
server = new ServerSocket(port);
}
catch (IOException ioe){ ioe.printStackTrace(); }
// don't release me into the wild yet!
// new Thread(this, "Server").start();
}
#Override
public void run(){
}
}