We wanted to execute some commands on Windows Server 2008/Windows 7 using telnet. As everytime logining in and running commands on around 50 of the same is tedious so I searched in google and zeored to apache commons and I found an example.
It works but it is printing some junk characters (I'm thinking it is some issue with character encoding of Windows, I'm new to this).
package com.kiran.telnet;
import org.apache.commons.net.telnet.TelnetClient;
import java.io.InputStream;
import java.io.PrintStream;
public class AutomatedTelnetClient {
private TelnetClient telnet = new TelnetClient();
private InputStream in;
private PrintStream out;
private String prompt = ">";
public AutomatedTelnetClient(String server, String user, String password) {
try {
// Connect to the specified server
telnet.connect(server, 23);
// Get input and output stream references
in = telnet.getInputStream();
out = new PrintStream(telnet.getOutputStream(), true);
// Log the user on
readUntil("login: ");
write(user);
readUntil("password: ");
write(password);
// Advance to a prompt
readUntil(prompt + " ");
} catch (Exception e) {
e.printStackTrace();
}
}
public void su(String password) {
try {
write("su");
readUntil("Password: ");
write(password);
prompt = ">";
readUntil(prompt + " ");
} catch (Exception e) {
e.printStackTrace();
}
}
public String readUntil(String pattern) {
try {
char lastChar = pattern.charAt(pattern.length() - 1);
StringBuffer sb = new StringBuffer();
boolean found = false;
char ch = (char) in.read();
while (true) {
System.out.print(ch);
sb.append(ch);
if (ch == lastChar) {
if (sb.toString().endsWith(pattern)) {
return sb.toString();
}
}
ch = (char) in.read();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void write(String value) {
try {
out.println(value);
out.flush();
System.out.println(value);
} catch (Exception e) {
e.printStackTrace();
}
}
public String sendCommand(String command) {
try {
write(command);
return readUntil(prompt);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void disconnect() {
try {
telnet.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
AutomatedTelnetClient telnet = new AutomatedTelnetClient(
"127.0.0.1", "Kiran", "artha");
System.out.println("Got Connection...");
telnet.sendCommand("hostname");
//telnet.sendCommand("ipconfig");
//telnet.sendCommand("ps -ef ");
//System.out.println("run command");
//telnet.sendCommand("ls ");
//System.out.println("run command 2");
telnet.disconnect();
System.out.println("DONE");
} catch (Exception e) {
e.printStackTrace();
}
}
}
The Output while I run this is:
Welcome to Microsoft Telnet Service
login: Kiran
Kiran
password: artha
[1;1H*=============================================================== [2;1HMicrosoft Telnet Server. [3;1H*=============================================================== [4;1HC:\Users\Kiran> Got Connection...
hostname
[5;1H[K[6;1H[K[7;1H[K[8;1H[K[9;1H[K[10;1H[K[11;1H[K[12;1H[K[13;1H[K[14;1H[K[15;1H[K[16;1H[K[17;1H[K[18;1H[K[19;1H[K[20;1H[K[21;1H[K[22;1H[K[23;1H[K[24;1H[K[25;1H[K[4;16Hhostname[5;1HKiran-PC[7;1HC:\Users\Kiran>DONE
And some ESC char before "["
Any help regarding this one.
Thank You.
Take a look at this wiki article. This symbols are just control characters, used to format the output in your terminal.
You can try to configure your terminal type like:
TelnetClient telnet = new TelnetClient("dumb");
Or you can try to configure it with TerminalTypeOptionHandler.
By default your telnet client is created with terminal type vt100' which supports control sequences. The dumb one does not support them. But you have to understand, that it is not guaranteed, that remote server support this terminal type.
Related
Im flabbergasted.
I took code from https://docs.oracle.com/javase/tutorial/networking/sockets/examples/EchoServer.java
for the server. And
https://docs.oracle.com/javase/tutorial/networking/sockets/examples/EchoClient.java
for the Client. I made minor changes. Mostly so that there is no back and forth echoing. Rather the Server should constantly with 2 second delays send same string. But I just cant understand why the client isnt working.
It sends the Exception message:
Couldn't get I/O for the connection to 127.0.0.1
I run the server with: java 6788
and the client with: 127.0.0.1 6788
I tried other ports.
I do this in eclipse so I set the arguments in Runconfiguration before running the classes. I start the server first. I tried in terminal outside of eclipse. Nothing makes it work.
Basically, the client should connect to server and output with System.out.println() what the server in turn outputs to the client. But nothing happens.
what is wrong?
Client:
import java.io.*;
import java.net.*;
public class EchoClient {
public static void main(String[] args) throws IOException {
if (args.length != 2) {
System.err.println(
"Usage: java EchoClient <host name> <port number>");
System.exit(1);
}
String hostName = args[0];
int portNumber = Integer.parseInt(args[1]);
try (
Socket echoSocket = new Socket(hostName, portNumber);
BufferedReader in =
new BufferedReader(
new InputStreamReader(echoSocket.getInputStream()));
) {
String userInput;
while (true) {
System.out.println("recieved: " + in.readLine());
}
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + hostName);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to " +
hostName);
System.exit(1);
}
}
}
Server:
import java.net.*;
import java.io.*;
public class EchoServer {
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.err.println("Usage: java EchoServer <port number>");
System.exit(1);
}
int portNumber = Integer.parseInt(args[0]);
System.out.println(args[0]);
InetAddress add = InetAddress.getLocalHost();
System.out.println(add.getHostAddress());
try (
ServerSocket serverSocket =
new ServerSocket(Integer.parseInt(args[0]));
Socket clientSocket = serverSocket.accept();
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream());
) {
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.println("HELLO!");
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}
You have to send the answer to the client.
Add a out.flush();
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.println("HELLO!");
out.flush();
}
As in the comment I eventually found a solution. BufferedReader.readLine() "blocked". When reading from a file it returns a line after reading up to a newline character, if I understand it correctly.
But since it was "A steady flow" from server with no newlines, it just kept "reading" and never returned a String.
I then tried using BufferedReader.read() method, that reads character by character, and returns after each char (thus never blocking). It then prints each character as it arrives, also it listens for a newline being sent from server, and once a read character equals a newline, it then prints a newline instead. Sort of emulating the "read line" behaviour I was expecting from original question.
Reading part of client:
while(true) {
character = (char) reader.read();
if(Character.isISOControl(character)) {
System.out.println();
}
else {
System.out.printf("%c", character);
}
}
Sending Part of Server:
private String message = "HELLO\n";
...
while(true) {
try {
Thread.sleep(2000);
writer.write(message);
writer.flush();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I have one client file clientRPC.java and server file serverRPC.java. Both communicate using TCP protocol and use objectinput and output stream to transfer data.
my client file:
public class clientRPC {
public static void main(String args[]) {
Socket s = null;
try {
int serverPort = 8888;
s = new Socket("localhost", serverPort);// server name is local host
//initializing input and output streams object and referencing them to get input and output
ObjectInputStream in = null;
ObjectOutputStream out = null;
out = new ObjectOutputStream(s.getOutputStream());
in = new ObjectInputStream(s.getInputStream());
MathsTutor mt = new MathsTutor();
out.writeObject(mt);
out.flush();
System.out.println("Welcome to Maths Tutor Service. The available maths exercises are:\n"
+ "Addition: Enter 'A' or 'a'\n"
+ "Subtraction: Enter 'S' or 's'\n"
+ "Multiplication: Enter 'M' or 'm'\n"
+ "Division: Enter 'D' or 'd'\n"
+ "Enter 'Q' or 'q' to quit");
//System.out.println();
MathsTutor mt1 = (MathsTutor) in.readObject();
String response = in.readUTF();
System.out.println(response);
} catch (UnknownHostException e) {
System.out.println("Socket:" + e.getMessage());
} catch (EOFException e) {
System.out.println("EOF:" + e.getMessage());
} catch (IOException e) {
System.out.println("readline:" + e.getMessage());
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} finally {
if (s != null) {
try {
s.close();
} catch (IOException e) {
System.out.println("close:" + e.getMessage());
}
}
}
}
}
and my server file :
public class serverRPC extends Thread {
String request;
String response;
public static void main(String args[]) {
try {
int serverPort = 8888;
ServerSocket listen_socket = new ServerSocket(serverPort);
while (true) {
Socket clientSocket = listen_socket.accept();
Connection c = new Connection(clientSocket);
}
} catch (IOException e) {
System.out.println("Listen socket:" + e.getMessage());
}
public serverRPC(String s) {
request = s;
}
}
class Connection extends Thread {
ObjectInputStream in;
ObjectOutputStream out;
Socket clientSocket;
public Connection(Socket aClientSocket) {
try {
clientSocket = aClientSocket;
in = new ObjectInputStream(clientSocket.getInputStream());
out = new ObjectOutputStream(clientSocket.getOutputStream());
this.start();
} catch (IOException e) {
System.out.println("Connection:" + e.getMessage());
}
}
public void run() {
try {
MathsTutor mt = (MathsTutor) in.readObject();
InetAddress ip = clientSocket.getInetAddress();
System.out.println("The Received Message from Client at address:/" + ip.getHostAddress());
System.out.println("====================================");
MathsTutor mt1 = new MathsTutor();
out.writeObject(mt1);
while(true) {
// Read from input
String command = in.readUTF();
System.out.println(command);
}
//System.out.println();
} catch (EOFException e) {
System.out.println("EOF:" + e.getMessage());
} catch (IOException e) {
System.out.println("readline:" + e.getMessage());
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {/*close failed*/
}
}
}
}
The problem is when I run server and then client on cmd, the client side displays the welcome msg and puts cursor on another line for user input but, I can't type anything, the cursor just blinks... I know this might be simple but it has taken already 3 hours for me and I'm stuck in the same thing.
The cursor marked with red keeps blinking but doesn't let me type anything.
You're writing an object with writeObject() and trying to read it with readUTF(). Illogical.
objects written with writeObject() must be read with readObject().
strings written with writeUTF() must be read with readUTF().
primitives written with writeXXX() must be read with readXXX(), for most values of X.
My requirement is to connect to some server through telnet using a java program and run few commands and read the responses. Based on these responses I need to perform some operation
I strated with https://stackoverflow.com/a/1213188/1025328
I'm using commons-net and my program is something like this:
public class TelnetSample {
private TelnetClient telnet;
private InputStream in;
private PrintStream out;
public TelnetSample(String server, int port) {
try {
// Connect to the specified server
telnet = new TelnetClient();
telnet.connect(server, port);
in = telnet.getInputStream();
out = new PrintStream(telnet.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
public String readResponse() {
System.out.println("TelnetSample.readResponse()");
StringBuilder out = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(out.toString());
System.out.println("==========================================================");
return out.toString();
}
public String read2() {
System.out.println("TelnetSample.read()");
StringBuffer sb = new StringBuffer();
try {
int available = in.available();
for (int index = 0; index < available; index++) {
char ch = (char) in.read();
System.out.print(ch);
sb.append(ch);
}
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
public String sendCommand(String command) {
try {
InputStream is = new ByteArrayInputStream(command.getBytes());
int ch;
while ((ch = is.read()) != -1) {
out.write(ch);
out.flush();
}
System.out.println(command);
String output = read2();
if (output.trim().isEmpty()) {
System.out.println("output empty");
} else {
System.out.println(output);
}
System.out.println("==========================================================");
return output;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void disconnect() {
try {
telnet.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
TelnetSample telnet = new TelnetSample("aspmx2.xxxxxx.com", 25);
telnet.readResponse();
telnet.sendCommand("Helo hi");
telnet.sendCommand("mail from:xyz#testmail.com");
telnet.sendCommand("rcpt to:pk#testmail.com");
telnet.sendCommand("quit");
telnet.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here apart form the telnet connection response, for every other sendCommand I'm getting an empty response. Can some one point me what could be the issue.
My output is something like this
TelnetSample.readResponse()
220 mx.xxxxxx.com ESMTP o86si4086625pfi.217 - gsmtp
==========================================================
Helo hi
TelnetSample.read()
output empty
==========================================================
mail from:xyz#testmail.com
TelnetSample.read()
output empty
==========================================================
rcpt to:pk#testmail.com
TelnetSample.read()
output empty
==========================================================
quit
TelnetSample.read()
output empty
==========================================================
This code has several issue:
the first issue is in readResponse method. When you use
readLine() you can easy block your code and will wait forever. Please have a look at discussion How to determine the exact state of a BufferedReader?
the second you don't send any CR/LF chars. Server got your requests like a single line. Ex:
mail from:xyz#testmail.comrcpt to:pk#testmail.comquit
To fix first issue you can choose several ways:
use multi-threading model
use NIO API. I would recommend Netty for that. Especially for your case as i can see you didn't use Telnet protocol at all, you connected to SMTP server.
Quick fix but the worst, wait first line from server and go on:
public String readResponse() {
System.out.println("TelnetSmtpSample.readResponse()");
StringBuilder out = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
out.append(reader.readLine());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(out.toString());
System.out.println("=====================");
return out.toString();
}
To fix second one:
telnet.sendCommand("Helo hi\r\n");
telnet.sendCommand("mail from:xyz#testmail.com\r\n");
telnet.sendCommand("rcpt to:pk#testmail.com\r\n");
telnet.sendCommand("quit\r\n");
It's possible read2 is getting a null value back from the input stream before data is actually returned. Try something like this:
private String read2() {
StringBuffer sb = new StringBuffer();
try {
do {
if (in.available() > 0) {
char ch = (char) in.read();
sb.append(ch);
} else {
Thread.sleep(1000);
}
} while (in.available()>0);
String output = new String(sb);
return output;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
I have already created simple instant messaging application in Java using Sockets and Swing. Right now it's communicating by resolving the hostname (PC name) or IP that's passes as a parameter. But is there a way to make it send a message with the Windows user ID (i.e. the user ID you use when you logon to Windows) as the parameter? This seems be easily done in C#, but how do I do it in Java?
Getting the username can be done using System.getProperty:
String name = System.getProperty("user.name");
This seems be easily done in C#
A 3rd party app (Winsent's Sent utility - winsentmessenger.com/sent) apparently can do this.
http://www.winsentmessenger.com/netsend/
The application in question is simply a wrapper around net send.
You could do the same, and invoke the process directly.
A solution lifted from:
http://members.iinet.net.au/~alw1746/awhome/freeware/WinPopup_java.txt
/*
WinPopup: send message to PC(s) on a Windows network from a Java program (like winpopup or net send).
Usage:
java WinPopup "user1,user2,..." "message"
eg. java WinPopup "peter" "where are you?" or java WinPopup 192.168.14.20 "Hello"
Build:
javac WinPopup.java
Alex Wong, Feb 2001
*/
import java.util.*;
import java.text.*;
import java.io.*;
public class WinPopup {
public static void main(String args[]) throws Exception {
String status;
if (args.length < 2) {
System.out.println("Usage: java WinPopup \"user1,user2,...\" \"msg\"");
System.exit(1);
}
if (args[0].length() < 1) {
System.out.println("User not found");
System.exit(1);
}
if (args[1].length() < 1) {
System.out.println("Message not found");
System.exit(1);
}
WinPopup popup=new WinPopup();
status=popup.alert(args[0],args[1]);
if (!status.equals("OK"))
System.out.println(status);
}
public String alert(String users,String msg) {
//loop thru list of users and net send the msg.
String buf,userList,user;
StringBuffer popup;
int ulen;
try {
if (users.length() < 1)
throw new Exception("User list not found.");
if (msg.length() < 1)
throw new Exception("Message not found.");
popup=new StringBuffer();
StringTokenizer st=new StringTokenizer(users,",");
while (st.hasMoreTokens()) {
buf=st.nextToken();
popup.append(buf).append(",");
}
if (popup.length() > 0) {
popup=popup.deleteCharAt(popup.length()-1);
userList=popup.toString();
ulen=userList.length();
for (int start=0,fin=0; fin <= ulen; fin++) {
if ((fin==ulen && fin > start) || userList.charAt(fin)==',') {
user=userList.substring(start,fin);
dosCmd("net send "+user+" \""+msg+"\"");
fin++;
start=fin;
}
}
}
return "OK";
}
catch (Exception e) {
return e.toString();
}
}
public void dosCmd(String cmd) {
//spawns a DOS process to run the net send command.
java.lang.Runtime rt;
Process proc;
try {
rt=java.lang.Runtime.getRuntime();
proc=rt.exec("c:\\winnt\\system32\\cmd.exe /C "+cmd);
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR");
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT");
errorGobbler.start();
outputGobbler.start();
int exitVal=proc.waitFor();
}
catch (Exception e1) {
System.out.println("dosCmd exception.");
System.out.println(e1.toString());
}
}
class StreamGobbler extends Thread {
//eat all stderr and stdout output.
InputStream is;
String type;
StreamGobbler(InputStream is, String type) {
this.is = is;
this.type = type;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null)
;
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}
I'm trying to enter some value in external application using Java.
Java application looks like this:
Runtime runtime = Runtime.getRuntime();
// ... str build ...
proc = runtime.exec(str);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
bw.write(value);
bw.flush();
bw.close();
if (proc.waitFor() != 0)
// error msg
// the end
Application hangs at waitFor method.
External application looks like this:
welcome banner
please enter 8 character input:
Welcome banner is printed using printf and input is taken with SetConsoleMode/ReadConsoleInput. ReadConsoleInput reads one char and they are masked with * character.
Help
you can use:
proc.getOutputStream().write("some date".getBytes())
keep in mind that you HAVE to read everything the app send to stdout and stderr, else it might get stuck writing there.
I use a generic class to read it in a different thread.
usage is like:
InputStreamSucker inSucker = new InputStreamSucker(proc.getInputStream());
InputStreamSucker errSucker = new InputStreamSucker(proc.getErrorStream());
proc.waitFor();
int exit = process.exitValue();
inSucker.join();
errSucker.join();
InputStreamSucker code is here:
public class InputStreamSucker extends Thread
{
static Logger logger = Logger.getLogger(InputStreamSucker.class);
private final BufferedInputStream m_in;
private final ByteArrayOutputStream m_out;
private final File m_outFile;
public InputStreamSucker(InputStream in) throws FileNotFoundException
{
this(in, null);
}
public InputStreamSucker(InputStream in, File outFile) throws FileNotFoundException
{
m_in = new BufferedInputStream(in, 4096);
m_outFile = outFile;
m_out = new ByteArrayOutputStream();
start();
}
#Override
public void run()
{
try
{
int c;
while ((c = m_in.read()) != -1)
{
m_out.write(c);
}
}
catch (IOException e)
{
logger.error("Error pumping stream", e);
}
finally
{
if (m_in != null)
{
try
{
m_in.close();
}
catch (IOException e)
{
}
}
try
{
m_out.close();
}
catch (IOException e)
{
logger.error("Error closing out stream", e);
}
if (m_outFile != null)
{
byte data[] = m_out.toByteArray();
if (data.length > 0)
{
FileOutputStream fo = null;
try
{
fo = new FileOutputStream(m_outFile);
fo.write(data);
}
catch (IOException e)
{
logger.error("Error writing " + m_outFile);
}
finally
{
try
{
if (fo != null) fo.close();
}
catch (IOException e)
{
logger.error("Error closing " + m_outFile);
}
}
}
}
}
}
public String getOutput()
{
return new String(m_out.toByteArray());
}
}
Got the answer! The trick is to use WriteConsoleInput() API because program expects keyboard event, not text ... That's why the waitFor() waited forever! :)