I have a method that gets the subnet mask using android shell command. I tested on adb and works; however, I just put it in a method and I can get the output displayed on the android monitor console. If there's an easier way please advise. Thanks. By the way I'm running this in main activity thread (no Asynctask)
/*
* method to return private subnet mask
*/
public String getPrivateSubnet() {
String output = "";
final String SUBNET_CMD = "/system/bin/ifconfig wlan0 | find \"Mask\"";
try {
Process p = Runtime.getRuntime().exec(SUBNET_CMD);
// p.wait();
Log.v("SUBNET OUTPUT", p.toString());
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
Log.v("SUBNET", inputLine);
}
in.close();
} catch (IOException ex) {
ex.printStackTrace();
}
Log.v("SUBNET", output);
return output;
}
If you wish to use ifconfig use:
ifconfig wlan0 | awk '/netmask/{print $4}'
EDIT: I did some really quick coding of myself to find this one. Yes the Java API lets you use the NetworkInterface class to get the ipv4 subnetmask of an interface. I made a piece of code that may be helpful for you. This code gives you the CIDR value of each interface (for example: 24 would be 255.255.255.0). See more on this here: https://en.wikipedia.org/wiki/IPv4_subnetting_reference
import java.net.*;
import java.util.Enumeration;
public class Main {
public static void main(String[] args) throws UnknownHostException, SocketException {
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = networkInterfaces.nextElement();
try {
for (InterfaceAddress address : networkInterface.getInterfaceAddresses()) {
System.out.println(address.getNetworkPrefixLength());
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
}
}
Related
I am new at stackoverflow and I am sorry if this kind of a question is asked before but did a quick search and I could not find any title like mine. I am working on a multi-client chat application on Java. I was following the tutorials and I can send messages that every user in the application can see. But I wonder how to create and send a private message to a spesific user into the chat.
import java.io.*;
import java.net.*;
import java.util.HashSet;
import java.util.Set;
public class ChatServer {
private int port;
private Set<String> userNames = new HashSet<>();
private Set<UserThread> userThreads = new HashSet<>();
public ChatServer(int port) {
this.port = port;
}
public static void main(String[] args) {
new ChatServer(9999).execute();
}
private void execute() {
try {
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("Server is running");
while (true) {
Socket socket = serverSocket.accept();
System.out.println("New user connected");
UserThread newUser = new UserThread(socket, this);
userThreads.add(newUser);
newUser.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void addUserName(String s) {
this.userNames.add(s);
}
public void broadcast(String serverMessage, UserThread excludeUser) {
for (UserThread aUser : userThreads) {
if (aUser != excludeUser)
aUser.sendMessage(serverMessage);
}
}
}
The code above is my server code.
public void run() {
Console console = System.console();
String userName = console.readLine("Enter your username : ");
writer.println(userName);
String text;
do {
text = console.readLine("[" + userName + "]: ");
if (text.startsWith("[")) {
isTargeted = true;
this.aimUserName = text.substring(text.indexOf("[") + 1, text.indexOf("]"));
//System.out.println("Private Message to: " + aimUserName);
} else {
isTargeted = false;
}
writer.println(text);
} while (!text.equals("bye"));
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
and this code above is a part of my write thread class. As you can see, if a message starts with '[name]' part, the "name" means the user that we want to send a private message. By doing this, I can get the name of the user that I want to send a private message but I could not figure out how to broadcast this message just to that spesific user. I believe I need to configure my broadcast function in ChatServer class but I don't really know how to do. What steps should I follow?
--Edit--
I've been working on my question and I did some additions to solve my problem. First of all, I think I should share everything I have to you. I shared my ChatServer class previously. Other classes I have are:
import java.io.IOException;
import java.net.Socket;
public class ChatClient {
public static void main(String[] args) {
new ChatClient().execute();
}
private void execute() {
try {
Socket socket = new Socket("localhost", 3);
System.out.println("Connected to chat server");
new ReadThread(socket, this).start();
new WriteThread(socket, this).start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
import java.net.*;
import java.io.*;
public class ReadThread extends Thread{
private BufferedReader reader;
private Socket socket;
private ChatClient client;
public ReadThread(Socket socket, ChatClient client) {
this.socket = socket;
this.client = client;
InputStream input;
try {
input = this.socket.getInputStream();
this.reader = new BufferedReader(new InputStreamReader(input));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
while(true) {
try {
String response = this.reader.readLine();
System.out.println("\n" + response);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
break;
}
}
}
}
import java.net.Socket;
import java.io.*;
public class UserThread extends Thread {
private Socket socket;
private ChatServer server;
PrintWriter writer = null;
public String userName;
public UserThread(Socket socket, ChatServer chatServer) {
this.socket = socket;
this.server = chatServer;
}
public void run() {
try {
InputStream input = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
OutputStream output = socket.getOutputStream();
writer = new PrintWriter(output,true);
String userName = reader.readLine();
this.userName = userName;
server.addUserName(userName);
String serverMessage = "New user connected: " + userName;
server.broadcast(serverMessage,this);
String clientMessage;
do {
clientMessage = reader.readLine();
serverMessage = "[" + userName + "] : " + clientMessage;
server.broadcast(serverMessage, this);
}while(!clientMessage.equals("bye"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void sendMessage(String serverMessage) {
writer.println(serverMessage);
}
}
import java.net.*;
import java.io.*;
public class WriteThread extends Thread {
private Socket socket;
private ChatClient client;
private PrintWriter writer;
public WriteThread(Socket socket, ChatClient client) {
this.socket = socket;
this.client = client;
OutputStream output;
try {
output = socket.getOutputStream();
this.writer = new PrintWriter(output, true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
Console console = System.console();
String userName = console.readLine("Enter your username : ");
writer.println(userName);
String text;
do {
text = console.readLine("[" + userName + "]: ");
if(text.startsWith("[")){
String aimUserName = text.substring(text.indexOf("[")+1,text.indexOf("]"));
System.out.println("Private Message to: " + aimUserName);}
writer.println(text);
}while(!text.equals("bye"));
/*do {
text = console.readLine("[" + userName + "]: ");
writer.println(text);
}while(!text.equals("bye"));*/
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
These codes work properly and I can multi-chat very clean. But while working on private chat stuff, I added to the ChatServer the line of:
public void privatebr(String serverMessage, String targetUserName){
for(UserThread aUser: userThreads){
if(aUser.userName == targetUserName)
aUser.sendMessage(serverMessage);
}
to the UserThread, I edited the part as:
String clientMessage;
do {
clientMessage = reader.readLine();
serverMessage = "[" + userName + "] : " + clientMessage;
if(clientMessage.startsWith("[")){
String targetUserName = clientMessage.substring(clientMessage.indexOf("[")+1,clientMessage.indexOf("]"));
serverMessage = "[" + userName + "] : " + clientMessage;
server.privatebr(serverMessage, targetUserName);
}else{
server.broadcast(serverMessage, this);
}
}while(!clientMessage.equals("bye"));
But when I did all these edits, the normal multi-chat progress became broken where is my fault? Why everything has broken?
Good question! To answer the question you asked is that you should maintain a Map of Users to their Socket connections, so that way with DMs you can just select the user(s) that you want to message. You will also need a messaging protocol for that (see below)
...But I have to tell you that using Sockets and SocketServer classes in today's day and age is like re-inventing the wheel. The place to start in doing a chat server is using the web sockets protocol. Even under this, you will probably want to define a message protocol (like I did - I created a messaging protocol using JSON and message types, where the string message in the websocket event onMessage first gets parsed into an object)
There are implementations for supporting WS on all platforms: java, .net, python, php etc. This should be your starting point.
--- Update ---
I understand where you are coming from. To help you along in understanding Sockets / ServerSockets, here are a couple of pointers & resources
DatagramSockets (aka UDP): This is a different transmission protocol than the regular TCP, used by Shockwave and then Flash, and is the fundamental reason that Flash is problematic. I strongly recommend against this
Data & Object Input/OutputStreams: "Data" streams are Java only (can't connect to technologgy built on other platforms). Object streams are similar, except you are transporting actual whole objects through the stream (also Java only) No one* (almost no one) uses these anymore.
SocketException: Using java.net.[Server]Socket(s), you are likely to encounter this exception. It happens when you are waiting for more data (through a read / readLine call) on a socket, and the socket closes. It took me a long time to figure this out, but THIS EXCEPTION IS YOUR FRIEND! You get it when the connection has closed (either on the client or server side). It allows the thread that was waiting on the socket to wake up, and allows you to do whatever clean-up you need to do. SocketException is a subclass of IOException, so you may not even realize what this is. But now at least I have warned you
Streams vs. Writers and Readers: Writers and Readers are for interpreting raw bytes as Java characters and Strings. This is necessary, as there are multiple text formats (i.e. ascii, windows-xx, utf-8, utf-16). Readers and Writers help you read and write text in different text formats (and also interpreting Images from image formats).
Buffered Writers and Streams: These are for INEFFICIENT reading and writing. For writing, this means enabling you to write part of a message and not send it until you are ready. For reading, this means reading streams line by line for example rather than reading everything at one go.
TUS: tjacobs/io - https://sourceforge.net/p/tus/code/HEAD/tree/tjacobs/io/ this is an old collection of Java libraries I put on SourceForge years ago, but a lot of the classes here pertain to dealing with Sockets. In particular, see SocketServerEx, DataFetcher, Main/App, Timeout, and maybe IOUtils. And of everything, really look at DataFetcher which is a lightweight threadableframework for Callback I/O listening.
Good luck and have fun!
I get this error basically less then an hour after i fire this nohup java -cp server.jar:mysql-connector.jar com.server.test.EchoMulti &. The error:
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Unknown Source)
at com.server.test.EchoMulti.main(EchoMulti.java:14)
I'm new to servers and Java. This is the first thing I did on a server and in Java and it's a multiplayer for Android game. The game is doing quite good so there are many people trying to play the multiplayer. I already fixed the mySQL max_connections but now i got whis problem. I would also like to know if there is a way to restart process automatically when it gets an error that causes a crach. And a way to automatically start it on reboot.
The EchoMulti class that's causing it:
package com.server.test;
import java.net.*;
import java.io.*;
public class EchoMulti {
public static void main(String[] args) throws IOException {
int portNumber = 25003;
boolean listening = true;
try (ServerSocket serverSock = new ServerSocket(portNumber)) {
while (listening) {
new EchoServer(serverSock.accept()).start();
}
} catch (IOException e) {
System.err.println("Could not listen on port " + portNumber);
System.exit(-1);
}
}
}
The EchoServer class:
package com.server.test;
import java.net.*;
import java.io.*;
import java.sql.*;
import java.lang.Thread;
public class EchoServer extends Thread {
private Socket sock = null;
public EchoServer(Socket sock) {
super("EchoServer");
this.sock = sock;
}
public void run(){
String url = "jdbc:mysql://IP:3306/DB";
String username = "USER";
String password = "PASSWORD";
Connection con = null;
Statement sta = null;
ResultSet resultSet = null;
try {
//System.out.println("Connecting database...");
con = DriverManager.getConnection(url, username, password);
//System.out.println("Database connected!");
} catch (SQLException e) {
throw new RuntimeException("Cannot connect the database!", e);
}
try (
PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
if(inputLine.equalsIgnoreCase("get")){
SEND SOMETHING
} else {
String catched[] = inputLine.split("\\;");
if(catched[0].equalsIgnoreCase("sub")){
SEND SOMETHING
} else if(catched[0].equalsIgnoreCase("res")){
SEND SOMETHING
}
}
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port 25003 or listening for a connection");
System.out.println(e.getMessage());
} finally {
//System.out.println("Closing the connection.");
if (con != null) try { con.close(); } catch (SQLException ignore) {}
try { sock.close(); } catch (IOException ignore) {} finally {}
}
}
public void close() throws IOException {
if (sock != null) sock.close();
}
}
You can also have a memory leak somewhere, or something preventing the correct garbage collection of used memory.
I would do the following three things.
Modify the EchoServer class
You can add a static member to understand if, when the crash occurs, the number of existing thread in memory is the one you expect (they should be as many as the connected players).
public class EchoServer extends Thread {
private Socket sock = null;
private static Integer CONNECTED = 0;
public EchoServer(Socket sock) {
try{
super("EchoServer");
this.sock = sock;
CONNECTED++;
} catch (Exception ex)
{
Logger.getLogger(EchoServer.class.getName()).log(Level.SEVERE, "Currently CONNECTED: "+CONNECTED);
}
}
.... your stuff here
#Override
public void finalize(){
super.finalize();
CONNECTED--;
}
}
If have more threads than connected players something is wrong.
Use a profiler Use a profiler to observe the memory usage and identify bottlenecks. Also be sure there aren't "strange" objects surviving generations or that the memory is not increasing over time without an increment of the players. NetBeans has a nice profiler that can be connected via TCP to live apps too.
Use -Xmx Use java -Xmx1g to launch the server.
I made this code and it gives the following 3 errors! I need help to get away with these errors that are there in the attached image. The 3 errors that are arising aren't going away since i don't have much info about how to include system commands.
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class EventListeners extends Applet
implements ActionListener{
public void init(){
Button b = new Button("Ping");
b.addActionListener(this);
add(b);
}
public void actionPerformed(ActionEvent e){
runSystemCommand(String command)
{try {
Process p = Runtime.getRuntime().exec(command);
BufferedReader inputStream = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String s = "";
// reading output stream of the command
while ((s = inputStream.readLine()) != null) {
System.out.println(s);
}}
catch (Exception e) {
e.printStackTrace();
}}
public static void main(String[] args) {
String ip = "google.com";
runSystemCommand("ping " + ip);
}
}
![Errors][1]
You seem to be trying to write a function within a method. This is illegal in Java
Place you runSystemCommand method out side the actionPerformed method
public void actionPerformed(ActionEvent e) {
// Call runSystemCommand(...);
}
public void runSystemCommand(String command) {
try {
Process p = Runtime.getRuntime().exec(command);
BufferedReader inputStream = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String s = "";
// reading output stream of the command
while ((s = inputStream.readLine()) != null) {
System.out.println(s);
}
} catch (Exception e) {
e.printStackTrace();
}
}
Some caveats...
Applets run in a tight security sandbox. It will NOT allow you to run system commands. Even if it, you could possible be running on a Linux or Mac box instead of Windows.
If you want to start with GUI program, start with something like JFrame, much easier to work with
I would also suggest getting your hands on a suitable IDE
I am in the process of writing a simple program that extracts computer names from MySQL Database then stores those names into a String array list (this part works fine). After that I wrote a class and a method that takes a String as a parameter (which will be the computer name) and tries to ping it. Here is the code for that class:
public class Ping
{
public void pingHost(String hostName)
{
try
{
InetAddress inet = InetAddress.getByName(hostName);
boolean status = inet.isReachable(5000);
if (status)
{
System.out.println(inet.getHostName() + " Host Reached\t" + inet.getHostAddress());
}
else
{
System.out.println(inet.getHostName() + " Host Unreachable");
}
}
catch (UnknownHostException e)
{
System.err.println(e.getMessage() + " Can't Reach Host");
}
catch (IOException e)
{
System.err.println(e.getMessage() + " Error in reaching the Host");
}
}
The problem is that I keep getting UnknownHostException thrown for most computers even if I can ping them manually or if I hard code the computer name as the "hostName".
Here is what my main looks like:
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException
{
ArrayList <String> list = new ArrayList<String>();
MySQLConnect myConnection = new MySQLConnect();
myConnection.importData(list);
Ping pingComputer = new Ping();
pingComputer.pingHost(list.get(87));
}
Right now I'm just trying to experiment with one computer which is throwing UnknownHostException but can be pinged manually. Anyone have any idea why this is happening?
EDIT...
Just to explain this a little bit more. For example in main, if I pass these parameters to pingHost:
pingComputer.pingHost("ROOM-1234");
It pings fine and returns correct host name/address. But list.get(87) returns same host name "ROOM-1234" but throws UnknownHostException? This has got me really confused and not sure why its not working.
EDIT
Wow finally figured it out. Reason ping was working when I was passing the string directly like so "ROOM-1234", was because there were no white spaces and getting is from array like so list.get(87) returned same thing but when I checked charLength, it returned a different value :) So I just ended up using trim to get rid of white spaces and now itworks great.
pingComputer.pingHost(list.get(87).trim());
Thanks for all the suggestions!
Dear Actually the code you are using is to check whether the host is reachable or not.
Use following class to ping windows pc use ping method but for other than windows pc use isreachable.
package com.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Ping {
public Boolean IsReachable(String ipaddress) {
try {
final InetAddress host = InetAddress.getByName(ipaddress);
try {
return host.isReachable(3000);
} catch (IOException e) {
e.printStackTrace();
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
return false;
}
public Boolean ping(String ipaddress) {
Runtime runtime = Runtime.getRuntime();
String cmds = "ping " + ipaddress;
System.out.println(cmds);
Process proc;
try {
proc = runtime.exec(cmds);
proc.getOutputStream().close();
InputStream inputstream = proc.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
String line;
while ((line = bufferedreader.readLine()) != null) {
if (line.contains("Reply from " + ipaddress + ":")) {
return true;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
}
And use as below code
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
MySQLConnect myConnection = new MySQLConnect();
myConnection.importData(list);
Ping ping = new Ping();
if (ping.ping(list.get(87)) {
System.out.prinln("Online / Host is reachable");
} else {
System.out.prinln("Offline /Host is unreachable");
}
}
But I would suggest ping by ip address is better than pinging with computer name.
How to check the status of the windows services from a java program?
on the following example you can find how can you check windws service status and you can parsed to do certain action
import java.util.*;
import java.sql.*;
import java.io.*;
import java.text.*;
public class doscmd
{
public static void main(String args[])
{
try
{
Process p=Runtime.getRuntime().exec("sc query browser");
BufferedReader reader=new BufferedReader(new InputStreamReader(p.getInputStream()));
String line=reader.readLine();
while(line!=null)
{
if(line.trim().startsWith("STATE"))
{
if (line.trim().substring(line.trim().indexOf(":")+1,line.trim().indexOf(":")+4).trim().equals("1"))
System.out.println("Stopped");
else
if (line.trim().substring(line.trim().indexOf(":")+1,line.trim().indexOf(":")+4).trim().equals("2"))
System.out.println("Startting....");
else
if (line.trim().substring(line.trim().indexOf(":")+1,line.trim().indexOf(":")+4).trim().equals("3"))
System.out.println("Stopping....");
else
if (line.trim().substring(line.trim().indexOf(":")+1,line.trim().indexOf(":")+4).trim().equals("4"))
System.out.println("Running");
}
line=reader.readLine();
}
}
catch(IOException e1) { }
}
}
At the very least you should be able to launch a cmd.exe process with the command sc query service-name and parse the output to determine the status. Not pretty, but lacking a Java API to the Windows service manager this would be a viable alternative.
EDIT - Read the Javadoc for java.lang.ProcessBuilder, which will allow you to execute an external command. You should probably set the redirectErrorStream property so that you don't have to handle two input streams (stdout and stderr), making for a much simpler design.
This method will return true or false depending upon service is running or not.
public boolean checkIfServiceRunning(String serviceName) {
Process process;
try {
process = Runtime.getRuntime().exec("sc query " + serviceName);
Scanner reader = new Scanner(process.getInputStream(), "UTF-8");
while(reader.hasNextLine()) {
if(reader.nextLine().contains("RUNNING")) {
return true;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}