I am looking for a way to access running java program from command line. The best woud be something that does the following:
Starting java app:
bash$java -jar MyBundle.jar App
Accessing app:
bash$test.sh param1 param2
So, test.sh calls App from MyBundle.jar somehow and passes values param1 & param2.
Important: I am looking for very fast approach. App hold database connection and it is very expensive to start App every time I need access do DB.
I need solution that will work in Ubuntu and Debian. If it will work on Mac - great.
Any help is appreciated!
I think you need to take a client-server approach. You app is the server, it runs as a background process and listens for connections on some port. And your client makes requests to the server and gets back the response.
A fast and simple way of implementing this in java would be to wrap your app in the Jetty servlet container. You could set it up to return JSON responses for example, which are easy to process.
It would be quite straightforward to open a TCP/IP socket and use netcat from the shell.
Java code
final ServerSocket serverSocket = new ServerSocket(9050);
while (true) {
final Socket socket = serverSocket.accept();
java.util.logging.Logger.getAnonymousLogger().info("Accepted");
final BufferedReader br = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
final String input = br.readLine();
final BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()));
bw.write("You said [" + input + "]");
bw.flush();
socket.close();
}
Shell code
echo 'bla' | nc localhost 9050
You'd need to muck around with threads to keep the sockets open to serve multiple requests.
Related
I'm trying to write a socket program in Java that intercepts data/packets.
I've successfully written this in python:
import socket
def createListener(port):
srvSock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
srvSock.bind(('localhost', port))
srvSock.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
while True:
raw_data, addr = srvSock.recvfrom(65536)
print('data: ' , raw_data)
createListener(80)
This is my basic Java socket program
public static void main(String[] args) {
try{
ServerSocket ss = new ServerSocket(80);
Socket s = ss.accept();
DataInputStream dis = new DataInputStream(s.getInputStream());
String str = (String)dis.readUTF();
System.out.println("data: "+str);
ss.close();
} catch(IOException i){
System.out.println(i);
}
}
However, when run, it doesn't intercept all data moving through the port on the network like the python program does. Specifically this line srvSock.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) in the Python script enables the socket to listen to the port and capture/intercept the entirety of the data going through it.
I cannot find a Java alternative to this syntax or any solution to my problem at all for that matter.
I would appreciate any help in how to use sockets to intercept packets on a network port.
Thanks
Im fairly certain what you are trying to do cannot be done with Java. It looks like you are trying to use "promiscuous mode", but Java sockets cannot be started in promiscuous mode. Java sockets are an end-to-end implementation: they can't listen on the network port for all traffic. For sure the network port would have to be in promiscuous mode, but I don't think Java is the right choice for you.
The only thing I can think of that might get you there would be doing a native call in something like JNI, but I wouldn't even really know where to start with that.
Here is a really old post that I found that is kind of related: java socket and web programing
From the looks of it, you're trying to read incoming bytearrays as string lines.
If that is so, this is what I do to read lines without missing a single line (In Kotlin):
socket.getInputStream().bufferedReader(Charsets.UTF_8).forEachLine {
it -> { /* Do what you wanna do with the input */ }
}
In Java, it's much less abstract :
BufferedReader(InputStreamReader(socket.getInputStream(), Charsets.UTF_8), 8 * 1024)
Then, use lines from this buffered reader as a line sequence to read your incoming lines.
I was making a simple client which connected to another server via Java Sockets and would await messages from that server and modify a video game it is running.
Socket socket = new Socket(server, 6667);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream( )));
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream( )));
String line = null;
while ((line = reader.readLine( )) != null) {
System.out.println(line);
}
Currently the while loop occupies the entire main thread and a way to fix that would be to put this process on a separate thread. Best case scenario I would like to create a listener that gets pinged whenever the thread receives a new message and sends it off to interact with the main thread.
I was wondering whether there exists a built in layer for this kind of process in java sockets (like pubsub or onMessage) because it feels like a very popular use case. Please let me know if I've missed something like this in my search, I apologize for my ignorance and thank you in advance.
Edit:
TLDR:
I have a main thread which is being occupied by a game and I would like to read incoming messages from a server, is there any built in way to do it besides employing listeners the manual way?
I am connecting to "/bin/bash" in ubuntu using:
process = Runtime.getRuntime().exec(cmd);
Here cmd is a String with different commands that i read and write from process.
Now i have come across a situation, where i login to remote machiens using ssh and while reading writing information to ext process, for loggin out from remote machine, i have to send control character like:
CTRL + ] in order to logout the session gracefully and come back to my local machine. Assuming the cmd is a String type, how can i write this CTRL chracter to the process?
Control-] in ASCII is equivalent to 035 octal. In Java you can represent this as "\035".
Writer writer = new OutputStreamWriter(process.getOutputStream());
writer.write("\035");
writer.flush();
It is also equivalent to decimal value of 29 so if you can write a byte with a value of 29 then that will work as well.
OutputStream os = process.getOutputStream();
os.write(29);
os.flush();
I assume Control-] has to do with the remote program. You are talking about telnet? However writing "exit\n" will also close the remote bash.
Writer writer = new OutputStreamWriter(process.getOutputStream());
writer.write("exit\n");
writer.flush();
You can also, obviously, close the OutputStream which closes the STDIN of the remote process.
os.close();
I'd like to fetch a webpage, just fetching the data (not parsing or rendering anything), just catch the data returned after a http request.
I'm trying to do this using the high-level Class Socket of the JavaRuntime Library.
I wonder if this is possible since I'm not at ease figuring out the beneath layer used for this two-point communication or I don't know if the trouble is coming from my own system.
.
Here's what my code is doing:
1) setting the socket.
this.socket = new Socket( "www.example.com", 80 );
2) setting the appropriate streams used for this communication.
this.out = new PrintWriter( socket.getOutputStream(), true);
this.in = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );
3) requesting the page (and this is where I'm not sure it's alright to do like this).
String query = "";
query += "GET / HTTP/1.1\r\n";
query += "Host: www.example.com\r\n";
...
query += "\r\n";
this.out.print(query);
4) reading the result (nothing in my case).
System.out.print( this.in.readLine() );
5) closing socket and streams.
If you're on a *nix system, look into CURL, which allows you to retrieve information off the internet using the command line. More lightweight than a Java socket connection.
If you want to use Java, and are just retrieving information from a webpage, check out the Java URL library (java.net.URL). Some sample Java code:
URL ur = new URL("www.google.com");
URLConnection conn = ur.openConnection();
InputStream is = conn.getInputStream();
String foo = new Scanner(is).useDelimiter("\\A").next();
System.out.println(foo);
That'll grab the specified URL, grab the data (html in this case) and spit it out to the console. Might have to tweak the delimiter abit, but this will work with most network endpoints sending data.
Your code looks pretty close. Your GET request is probably malformed in some way. Try this: open up a telnet client and connect to a web server. Paste in the GET request as you believe it should work. See if that returns anything. If it doesn't it means there is a problem with the GET request. The easiest thing to do that point would be write a program that listens on a socket (more or less the inverse of what you're doing) and point a web browser to localhost:[correct port] and see what the web browser sends you. Use that as your template for the GET request.
Alternatively you could try and piece it together from the HTTP specification.
I had to add the full URL to the GET parameter. To make it work. Although I see you can specify HOST also if you want.
Socket socket = new Socket("youtube.com",80);
PrintWriter out = new PrintWriter(new BufferedWriter(new
OutputStreamWriter(socket.getOutputStream())));
out.println("GET http://www.youtube.com/yts/img/favicon_48-vflVjB_Qk.png
HTTP/1.0");
out.println();
out.flush();
Yes, it is possible. You just need to figure out the protocol. You are close.
I would create a simple server socket that prints out what it gets in. You can then use your browser to connect to the socket using a url like: http://localhost:8080. Then use your client socket to mimic the HTTP protocol from the browser.
Not sure why you're going lower down than URLConnection - its designed to do what you want to do: http://download.oracle.com/javase/tutorial/networking/urls/readingWriting.html.
The Java Tutorial on Sockets even says: "URLs and URLConnections provide a relatively high-level mechanism for accessing resources on the Internet. Sometimes your programs require lower-level network communication, for example, when you want to write a client-server application." Since you're not going lower than HTTP, I'm not sure what the point is of using a Socket.
I'd like to establish a server(Java)/client (Matlab) communication using socket. They can send messages to each other. An example shows how to do this in Java server and Java client, http://java.sun.com/docs/books/tutorial/networking/sockets/clientServer.html.
When I try to rewrite the client part in Matlab, I only can get the first message that the Java server sends and display it in the Matlab command window.
When I type a message in the Matlab command window, I can't pass it to the Java Server.
Jave code:
kkSocket = new Socket("localhost", 3434);
Matlab equivalent:
kkSocket = Socket('localhost', 3434);
Java code for client:
out = new PrintWriter(kkSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
What would be a Matlab equivalent for this? Thanks in advance.
For the input stream:
input_stream = input_socket.getInputStream;
d_input_stream = DataInputStream(input_stream);
For the output stream:
output_stream = output_socket.getOutputStream;
d_output_stream = DataOutputStream(output_stream);
If you are trying to use MATLAB and the Java application on the same machine then matlabcontrol may do everything that you are looking for. It automatically establishes a connection to a session of MATLAB. It uses Java's Remote Method Invocation under the hood which makes use of sockets. matlabcontrol is designed specifically to only enable communication on localhost; the sockets it creates will not accept remote connections due to the security issues that could allow. However, if you need to allow remote connections you may find parts of matlabcontrol's source code to be useful.