The title basically says it all but just but to reiterate:
I need my Java program to kill itself (dispose w/e) if a specific external program launches.
My java program uses a global hook that listens for mouse input, when I remote into a clients computer the mouse listener/GUI that my program creates can cause all kinds of issues with the mouse if used I'm while connected. To handle this I need my program to automatically "turn off" when the screen-connect application we use launches.
I am already using a global hook to capture mouse input, is there something similar I could use for system events maybe?
Depending on the version of windows respectively Java you are using there are various libraries you could be using to simply regularly "scan" the operating system for a list of running processes.
If something shows up that you don't like, simply react using System.exit for example.
In your first program, just create a new Thread and let it run. Put this code in the run method:
try {
ServerSocket socket = new ServerSocket(1111); // the paramater is a port and you can choose any port you want
socket.accept();
socket.close();
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
This will wait for a connection and once the connection is made, it will close itself. That is because the accept method that waits for a connection blocks until there is a connection made. That's why you put it in another thread.
After it recieves the connection it will unblock so the code will continue and exit the program! And it MUST be in another friend so it doesn't block your application!
In the second application, in the beginning just make a connection!
To make a connection use this code:
try (Socket socket = new Socket("localhost" ,1111);){
socket.close();
} catch (IOException e) {
}
This will connect it and once it does, the first program will close. Now just continue on with this program! If you don't understand the sockets the best, then check out this link. It is awesomely explained:
https://www.javaworld.com/article/2077322/core-java/core-java-sockets-programming-in-java-a-tutorial.html
Related
I'm writing a program that enables UDP communication between a KUKA robot (programmed in java) and a python server running on a PC. The program on the robot needs to run multiple methods concurrently because it needs to listen/receive messages on 3 sockets simultaneously (they all need to be listening for messages at all times).
I first tried this using multi-threading. My main class is DP_UDP_COMM which start running when the robot is started. When starting some initialization between the robot and python server is done to set up the socket connection, after that the communication processes need to be started. An example of 1 of these 'communication' threads is shown below as Thread UDP_COMM:
//DP_UDP_COMM class is the main class that gets started when the robot starts
public class DP_UDP_COMM extends RoboticsAPITask {
//Some code here
//One of the communication processes that needs to run while the DP_UDP_COMM instance is active
public Thread UDP_COMM = new Thread(new Runnable(){
public void run(){
while(running){
_log.info("Thread Started, Waiting for Action");
try {
ReceiveUDP();
_log.info("Buffer received is: "+String.valueOf(receive));
_log.info("Type received is: "+String.valueOf(ByteProcess.getType(receive)));
if(status==0)
processPacket(receive);
} catch (Exception e) {
// TODO Auto-generated catch block
send = createPacketResponse("ERROR: "+e.getMessage());
try {
SendUDP(send);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace(); }
e.printStackTrace();
}
}
}
});
UDP_COMM.start();
//Some code and other methods here
}
This thread tries to receive a UDP message from a socket using ReceiveUDP(). This is a blocking method so it keeps waiting here untill it receives a message. This message is then processed using processPacket(), which is a method that sends a command to the robot determined by the message that was received. After sending the command it starts listening again for new messages. This loops indefinitely when the robot is active.
The other threads are very similar but use slightly different methods which are bound to different sockets.(For example ReceiveUDPEmergency() which is the same as ReceiveUDP() but with a different socket)
This is working well with one thread, but when running 3 threads concurrently it doesn't work anymore because the threads will wait for each other to complete before looping because ReceiveUDP() is a blocking method.
The solution for this (I think) is to use multi-processing instead of multi-threading because this truly runs them in parallel instead of sequentially.
However when looking at the java.lang.Process documentation I really don't get how creating a process works. In every example they create/start a process from an external .exe file or something like that.
Is it possible to create multiple processes that run multiple methods in parallel within my DP_UDP_COMM instance? How would I do this?
//What have I tried:
As explained above I tried multi-threading at first. But this isn't good enough.
With multi-processing it is not clear how to start a process which just runs a method in parallel to the main instance.
I am creating a simple learning project (chat using sockets) in Java and today I faced a problem. Maybe the point is an obvious one for somebody, but I am confused with it
The purpose
To get to know (at least one of the following):
A list of the currently opened free/taken ports on a PC
Whether the port I want to use is locked
What I tried
I've created a simple raw-project and run two ServerSocket on one port. In this case I have caught a java.net.BindException with notification that "...Address already in use: JVM_Bind...". But in this way I am able to check the port avaliability only if my JVM has captured it. In case if other program listens to the port, I do not know anything about it. I am adding a code below.
public class Main {
public static void main(String[] args) throws IOException {
MyThread myThread = new MyThread();
ServerSocket serverSocket = new ServerSocket(5940);
myThread.start();
serverSocket.accept();
}
}
public class MyThread extends Thread {
#Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(5940);// exception is thrown here
serverSocket.accept();
} catch (IOException e) {
System.err.println("SECOND SERVER");
e.printStackTrace();
interrupt();
}
}
}
PS Any advice is warmly welcomed
I've created a simple raw-project and run two ServerSocket on one
port. In this case I have caught a java.net.BindException with
notification that "...Address already in use: JVM_Bind...". But in
this way I am able to check the port avaliability only if my JVM has
captured it. In case if other program listens to the port, I do not
know anything about it.
I think you're misinterpreting your result. I have every reason to believe that if the port you request is already bound by any process then your attempt to bind it will fail with a BindException. That takes care of
Whether the port I want to use is locked
. As for
A list of the currently opened free/taken ports on a PC
, there are system utilities that can get you that information, but it is useless to you. Whichever end initiates the connection (i.e. the client) needs to know in advance what port to try to connect to. It cannot get that from the server, because that presents a chicken & egg problem.
The usual approach is that the server listens to a specific port chosen by its developer or its admin, and that port number is provided to clients out of band -- often simply by it being a standard, well-known port number. That's how most of the basic network protocols work; for example, HTTP servers run on port 80 by default. If the wanted port happens to be unavailable when the server attempts to bind to it then that indicates a misconfiguration of the machine, and the server simply fails to start.
The client, on the other hand, does not need to choose a port number at all. The system will choose one for it automatically when it attempts to connect to the server.
I am looking for a bit of efficient code that can assist me in monitoring if a com port is still open using the RX/TX libraries.
Lets say I have a hardware device that communicates to the PC using a virtual com port and that device can be plugged in and out at any time. I want to show a connection status on the pc.
I have tried this with something like a buffered reader below and it registered that the device gets disconnected but I have to re-open the port from scratch in another method.
I am looking from something short like comPort.isOpen () or something?
// Set the value of is running
Start.isRunning = true;
// Check to see if the device is connected
while (Start.isRunning) {
// Try to connect to the device
try {
// Create a Buffered Reader
BufferedReader reader = new BufferedReader(
new InputStreamReader(serialPort.getInputStream()));
// Read the output
if (Character.toString((char) reader.read()).equalsIgnoreCase(
"^")) {
// Set the connected flag
Start.CONNECTED_FLAG = true;
// Set the connected fag
AddComponents.TFconnected.setText("Connected");
}
// Close the reader
reader.close();
// Let the thread sleep
Thread.sleep(500);
}
// Catch a error if the device is disconnected
catch (Exception err) {
// Set the connected flag
Start.CONNECTED_FLAG = false;
// Set the connected fag
AddComponents.TFconnected.setText("Disconnected");
// Let the thread sleep
Thread.sleep(500);
}
}
Disclaimer: Consider this a partial answer because I do not have intimate knowledge of the workings of serial ports, and my tests could not produce anything useful. Posting here regardless in the hopes any of this is helpful.
Unfortunately, as far as I know, there is no way to receive any kind of "connection / disconnection" event messages. Sadly, as I am not intimately familiar with the workings of serial ports, I cannot give you a full and proper explanation. However, from some research, one of the answers posted in that forum had this to say:
There's no event by the system to inform you of [a disconnection event] because that would require exclusive use of the COM port. If you have a SerialPort object created and have opened a port you should get a CDChanged when a devices is plugged in and unplugged from the serial port. That assumes the device follows the pins standards; not all devices do.
Note that the poster, and the link I've provided, are discussing this within the context of C#. However this seems to be related to how the ports work in general, regardless of language, so I am somewhat confident the same can be applied to RXTX Java.
There are some events you can attempt to listen for. In my tests I was only ever able to receive the DATA_AVAILABLE event, however my setup is a bit different (Raspberry PI) and I can't at the moment physically disconnect the device from the port, I can only attempt to block the device file (which may explain the failure of my test).
If you would like to attempt the event listening yourself, have your class implement SerialPortListener, register for the desired events, check the events in your serialEvent method. Here is an example:
public class YourClass implements SerialPortListener{
private SerialPort serialPort;
// ... serial port gets set up at some point ...
public void registerEvents(){
serialPort.addEventListener(this);
// listen to all the events
serialPort.notifyOnBreakInterrupt(true);
serialPort.notifyOnCarrierDetect(true);
serialPort.notifyOnCTS(true);
serialPort.notifyOnDataAvailable(true);
serialPort.notifyOnDSR(true);
serialPort.notifyOnFramingError(true);
serialPort.notifyOnOutputEmpty(true);
serialPort.notifyOnOverrunError(true);
serialPort.notifyOnParityError(true);
serialPort.notifyOnRingIndicator(true);
}
#Override
public void serialEvent(SerialPortEvent event) {
System.out.println("Received event. Type: " + event.getEventType() + ", old value: " + event.getOldValue() + ", new value: " + event.getNewValue());
}
}
If that ultimately fails, I believe the only other alternative is similar to your current solution; attempt to read from the port, and if it fails, consider it disconnected, and set your indicator accordingly. At each iteration, if it is disconnected, attempt to reconnect; if reconnect succeeds, reset your indicator to "connected".
Sorry I cannot be of more assistance. Hopefully some of that may lead to something useful.
Side Note:
If you want to DRY up your code slightly, put the Thread.sleep(500) in a finally block instead, since it appears to be executed regardless.
I have implemented a socket with a server and single client. The way it's structured currently, the server closes whenever the client closes. My intent is have the server run until manual shutdown instead.
Here's the server:
public static void main(String args[])
{
;
try
{
ServerSocket socket= new ServerSocket(17);
System.out.println("connect...");
Socket s = socket.accept();
System.out.println("Client Connected.");
while (true)
{
work with server
}
}
catch (IOException e)
{
e.getStackTrace();
}
}
I've tried surrounding the entire try/catch loop with another while(true) loop, but it does nothing, the same issue persists. Any ideas on how to keep the server running?
It looks like what's going to happen in your code there is that you connect to a client, infinitely loop over interactions with the client, then when someone disrupts the connections (closes clearning, or interrupts it rudly - e.g., unplug the network cable) you're going to get an IOException, sending you down to the catch clause which runs and then continues after that (and I'm guessing "after that" is the end of your main()?)...
So what you need to do is, from that point, loop back to the accept() call so that you can accept another, new client connection. For example, here's some pseudocode:
create server socket
while (1) {
try {
accept client connection
set up your I/O streams
while (1) {
interact with client until connection closes
}
} catch (...) {
handle errors
}
} // loop back to the accept call here
Also, notice how the try-catch block in this case is situated so that errors will be caught and handled within the accept-loop. That way an error on a single client connection will send you back to accept() instead of terminating the server.
Keep a single server socket outside of the loop -- the loop needs to start before accept(). Just put the ServerSocket creation into a separate try/catch block. Otherwise, you'll open a new socket that will try to listen on the same port, but only a single connection has been closed, not the serverSocket. A server socket can accept multiple client connections.
When that works, you probably want to start a new Thread on accept() to support multiple clients. Simplest way to do so is usually to add a "ClinentHandler" class that implements the Runnable interface. And in the client you probably want to put reading from the socket into a separate thread, too.
Is this homework / some kind of assignment?
In my software i need to send messages between client and server through an ObjectOutputStream.
The core of the sender method is the following:
....
try {
objWriter.writeUnshared(bean);
objWriter.flush();
} catch (Exception e) {
....
}
...
Running my application on windows XP when the network cable is removed the writeUnsahred throw me an exception.
Now i'm trying to run my application into ubuntu 12.10 and the method don't throw anything if i remove the cable!
Any hint??
Whether and when you get the exception depends on:
how large the socket send buffer is at your end
how large the socket receive buffer is at the peer
how much unacknowledged data you have already written
how long it is since you wrote that, and
the internal timers of your TCP stack.
The only part of that you can control from Java is your own socket send buffer. It is therefore entirely unpredictable when and if the exception will be delivered. You therefore must not write your application to depend on a specific behaviour.
Yes but following the methods called by writeUnshared and flush i see that write(OutputStream.class:106) is called and this method must generate an exception if the stream is closed... So i use that information to check if my channel is active.. the problem is that in ubuntu the channel seems to be open even if i remove the cable..