I am not very familiar with telnet so I would appreciate the help from any willing.
I have smart plugs which can be switch on or off through a telnet interface.
I always use telnet via command prompt to connect to the server Digi X4 connect port (via >telnet ). If I want to switch the socket on/off, I have to now type: "12 set pow=on/off" and press enter.
I would like to implement this through java using the telnet client. I am now able to connect to the port (thanks to the answers posted on this platform), but to send the command to switch devices on/off is proving difficult for me. I still have to type "12 set pow=on/off" and press enter. I would like Java to send this command.
Below is my java code. I would appreciate your assistance. Bab
public class TelnetConnection {
static TelnetClient tc = null;
public static void main(String[] a) throws Exception
{
String[] args = {"122.1222.181.45","8085"};
System.out.println("arg value: "+args);
if(args.length < 1)
{
System.err.println("Usage: Error <remote-ip> [<remote-port>]");
System.exit(1);
}
String remoteip = args[0];
int remoteport;
if (args.length > 1)
{
remoteport = (new Integer(args[1])).intValue();
}
else
{
remoteport = 7000;
}
tc = new TelnetClient();
while (true)
{
boolean end_loop = false;
try
{
tc.connect(remoteip, remoteport);
Thread reader = new Thread (new TelnetClientExample());
tc.registerNotifHandler(new TelnetClientExample());
System.out.println("TelnetClientExample");
reader.start();
OutputStream outstr = tc.getOutputStream();
PrintWriter out = new PrintWriter(outstr);
String buff = "11 set pow=on";
//int ret_read = 0;
do
{
try
{
out.print(buff);
outstr.flush();
}
catch (IOException e)
{
System.err.println("Error");
end_loop = true;
}
}
while((true) && (end_loop == false));
try
{
tc.disconnect();
}
catch (IOException e)
{
System.err.println("Error");
}
}
catch (IOException e)
{
System.err.println("Exception while connecting:" + e.getMessage());
System.exit(1);
}
}
}
}
Try tring buff = "11 set pow=on\n"; the server may need the newline to detect end-of-command.
By the way, the loop that infinitely sends that to the server looks worrisome.
You need to send a line terminator corresponding to 'and press Enter'.
The line terminator in Telnet is defined as \r\n.
Related
I have a java program on a computer that is the server and a program on the esp that acts as a client. They both connect to the local wifi and then to each other. The purpose is to have the computer send a number to the esp. I had managed to make them work, but then suddenly esp has stopped connecting to the server. I have spent quite some time trying to figure out what happened but I don't think I have changed anything. One day they all worked together, the next they didn't.
This is the main of my java code and I believe it works, even though it's probably not ideal (apart from this there are a couple of functions to make a small GUI and to do some actions):
createGUI();
//looking for the arduino port, to get data from it
SerialPort comPort = findArduinoPort();
if (comPort != null) {
System.out.println("Arduino port found: " + comPort.getSystemPortName());
} else {
System.out.println("Arduino port not found");
System.exit(0);
}
comPort.openPort();
comPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0);
InputStream inComPort = comPort.getInputStream();
ServerSocket listener = new ServerSocket(8020);
char lastRead;
String data = new String("0");
try{
while(true){
Thread.sleep(0);
if(myStatus == status.ON) {
//read data from aduino serial
if (inComPort.available() > 0) {
data = "";
while (true) {
lastRead = (char)inComPort.read();
if (lastRead == '\r') {
lastRead = (char)inComPort.read();
break;
} else {
data += lastRead;
}
}
}
System.out.println("Waiting for client");
//from my understanding the next line waits for the client to connect
Socket socket = listener.accept();
socket.setKeepAlive(true);
System.out.println("Client Connected");
try{
//i read data from the client, to make sure it's ready to receive
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Client response: " + in.readLine());
//I send the data to esp8266
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
System.out.println("Sending Message: " + data);
out.write(data);
out.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
socket.close();
}
}
}
} finally {
try {
inComPort.close();
} catch (Exception e) {
e.printStackTrace();
}
comPort.closePort();
listener.close();
}
}
After writing to console "Waiting for client" it waits for a client to connect (and to my understanding it works fine). The problem comes with the code in esp8266
#include <ESP8266WiFi.h>
#include <LiquidCrystal.h>
//wifi data
#define NAME "i_put_my_wifi_here"
#define PASSWORD "i_put_my_wifi_pw_here"
String host = "i_put_my_computer_ip_here";
const int port = 8020;
WiFiClient client;
//lcd display to write the data to
LiquidCrystal lcd(D2, D3, D5, D6, D7, D8);
void setup() {
Serial.begin(115200);
//lcd setup
lcd.begin(16, 2);
lcd.print("Puntamenti:");
lcd.setCursor(0, 1);
lcd.print("0");
WiFi.mode(WIFI_STA);
WiFi.begin(NAME, PASSWORD);
Serial.print("\nConnecting to wifi");
while(WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("Connected\n");
}
void loop() {
//i try to conect to the server
if (client.connect(host, port))
{
Serial.print("Connected to host: ");
Serial.println(host);
//i tell the server i'm ready for data
client.println("Connected");
Serial.print("Wating for data");
int i = 0;
while(true){
if(client.available() == 0){
Serial.print(".");
i++;
if(i >= 10){
break;
}
delay(1000);
} else {
lcd.setCursor(0, 1);
String streamData = client.readStringUntil('\n');
lcd.print(streamData);
Serial.print("\nData received: ");
Serial.println(streamData);
break;
}
}
client.stop();
} else {
Serial.println("Connection to host failed");
}
delay(1000);
}
So my problem comes with client.connect(host, port). Last time i tried the programs it worked fine. It returned true and the rest would happen. Since today, however it's always false, so esp connects to the wifi, like the computer, but then it always fails to connect to the server waiting for it. I can't understand where's the problem, and especially how it can be that it used to work well and now it doesn't anymore.
Well, this is awkward. After spending a day on this I restarted my modem and now it works fine, just like before.
Alright, thanks anyway guys
We have lowered the TCP KeepAlive time on our servers from the default 7200s to 500s.
I am trying to write a small java program to check the that server is in fact using these updated settings.
If I manually do a telnet to the host from the command line it times out as expected.
When I run this program the if (out.checkError()) is supposed to return true but it does not. What can be the issue?
public class keepAlive5 {
public static void main(String[] args) {
// String serverName = args[0];
//String serverName = args[0];
// int portNum = Integer.parseInt(args[1]);
// tstSocket.setKeepAlive(true);
int portNum = 5500;
int timeToWait = 600;
String serverName = “host1”;
try {
Socket tstSocket = new Socket(serverName, portNum);
PrintWriter out = new PrintWriter(tstSocket.getOutputStream(), true);
System.out.println("connected, now wait 10 minutes...");
TimeUnit.SECONDS.sleep(timeToWait);
System.out.println("Will now check the connection..");
out.write("try writing something");
out.flush();
if (!out.checkError()){
System.out.println("Socket closed by remote host");
}
} catch (Exception ex) {
//Exception
System.out.println("Unknown host..");
}
}
}
You need to write enough data so that the socket send buffer is filled, so that the write blocks, so that there is some possibilty of an error being detected and transmitted back to the application. Otherwise the writing process is asynchronous to the application, which will have closed the socket before the error is detected.
I would not use a PrintWriter for this task.
I followed this tutorial to make a chat with multiples client and one server: http://inetjava.sourceforge.net/lectures/part1_sockets/InetJava-1.9-Chat-Client-Server-Example.html
but I have a problem, I want the client to send his username when he starts the app via the command prompt like this:
java -jar Client.jar Jonny
but I don't know how to do this.
If someone can explain me..
Thanks for your answers.
If you input your parameters like java -jar Client.jar Jonny, you can get the argument in the Client class' main method as a String array.
For example you can print out the first argument like this:
public static void main(String[] args)
{
//This will output: "The first argument is: Jonny"
System.out.println("The first argument is: "+args[0]);
}
All you have to do now is send this to the server. If you use the NakovChat example it could be something like this:
public static void main(String[] args)
{
BufferedReader in = null;
PrintWriter out = null;
try {
// Connect to Nakov Chat Server
Socket socket = new Socket(SERVER_HOSTNAME, SERVER_PORT);
in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(
new OutputStreamWriter(socket.getOutputStream()));
System.out.println("Connected to server " +
SERVER_HOSTNAME + ":" + SERVER_PORT);
//We print out the first argument on the socket's outputstream and then flush it
out.println(args[0]);
out.flush();
} catch (IOException ioe) {
System.err.println("Can not establish connection to " +
SERVER_HOSTNAME + ":" + SERVER_PORT);
ioe.printStackTrace();
System.exit(-1);
}
// Create and start Sender thread
Sender sender = new Sender(out);
sender.setDaemon(true);
sender.start();
try {
// Read messages from the server and print them
String message;
while ((message=in.readLine()) != null) {
System.out.println(message);
}
} catch (IOException ioe) {
System.err.println("Connection to server broken.");
ioe.printStackTrace();
}
}
}
I am trying to relearn Java after 10 years of not touching it. I want to create a library using JSch from some other apps I am looking to write. I have the connections ironed out but I am using stdin and stdout right now.
I am looking to have a method that accepts a single command in a String and returns an ArrayList with the results.
Any assistance would be great!
//This vars are in the class.
private JSch _jsch;
private Session _session;
private Channel _channel;
Here is my connection method
public boolean Connect () throws JSchException
{
try {
_jsch = new JSch();
_session = _jsch.getSession(_user, _hostname, _port);
_session.setPassword(_password);
_session.setConfig("StrictHostKeyChecking", "no");
_channel = _session.openChannel("shell");
//((ChannelShell)_channel).setPtyType("vt100");
_channel.setInputStream(bais);
_channel.setOutputStream(baos);
_channel.connect(3000);
}//try to connect
catch (JSchException ex)
{
throw ex;
}
return true;
}
The goal is once I open the connection I can send this method a command and return the results in an array. Act based on the results and send more commands. I don't want to close the connection each time as they will build on the commands that come before it. I am not sure how to work with the Inputs and Output Streams enough to get the results I am looking for. If you can assist with filling out the following method, I would be grateful.
public List<String> ExecuteCommand (String command) {
//run command to existing connection
//Get returned lines to Array List and return the list
}
Thanks
Here's an example of running a local process and creating a return ArrayList filled line by line with the output from the process. Whilst it's not exactly what you want, it should give you an idea.
public List<String> ExecuteCommand (String command) {
Runtime r = Runtime.getRuntime();
Process p = r.exec(command);
p.waitFor();
BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
ArrayList<String> output = new ArrayList<String>();
while ((line = b.readLine()) != null) {
output.add(line);
}
return output;
}
I've created an open source project (click to see) to implements remote file system. Here is the most important code snippet, which also supports sudo. In the example, I redirect error output to standard output. If you do not want the error output, you can remove it. In the example, I use StringWriter instead of List<String>. I encourage you to use it.
/**
* Executes commands at target host.
* #throws IOException Failed to capture a return code
*/
public int exec(boolean sudo, String command, StringWriter output) throws IOException {
ChannelExec channel = null;
try {
channel = (ChannelExec) session.openChannel("exec");
sudo = sudo && !username.equals("root");
if (sudo) {
command = "sudo -S -p '' " + command;
channel.setPty(true);
}
channel.setCommand(command);
InputStream stdout = channel.getInputStream(); // The stream will be recycled automatically
InputStream stderr = channel.getErrStream(); // The stream will be recycled automatically
channel.connect();
boolean passwordEntered = false;
if (sudo && !StringUtils.isEmpty(password)) {
OutputStream stdin = channel.getOutputStream();
stdin.write(password.getBytes());
stdin.write("\n".getBytes());
IOUtils.closeQuietly(stdin);
passwordEntered = true;
}
String contents = readFully(stdout);
if (passwordEntered) {
contents = contents.substring(password.length());
}
output.write(contents.trim());
contents = readFully(stderr);
int retval = channel.getExitStatus();
if (retval != 0) {
output.append(contents.trim());
}
return retval;
}
catch (JSchException ex) {
throw new IOException(ex);
}
finally {
output.flush();
if (channel != null) {
channel.disconnect();
}
}
}
private static String readFully(InputStream input) throws IOException {
StringBuilder output = new StringBuilder();
int bytesRead = input.read();
while (bytesRead != -1) {
output.append((char) bytesRead);
bytesRead = input.read();
}
return output.toString();
}
Here is the solution I have currently. It could use some stream lining and clean up but it is getting me what I am looking for.
I didn't want to mark this as an answer but I haven't posted to this site before so excuse me if I did that wrong. Here is the new connect method
public boolean Connect () throws JSchException
{
try {
_jsch = new JSch();
_session = _jsch.getSession(_user, _hostname, _port);
_session.setPassword(_password);
_session.setConfig("StrictHostKeyChecking", "no");
_session.connect();
_channel = _session.openChannel("shell");
_channel.setInputStream(null);
_isInput = _channel.getInputStream();
_isOutput = _channel.getOutputStream();
_reader = new BufferedReader (new InputStreamReader(_isInput));
_writer = new BufferedWriter (new OutputStreamWriter (_isOutput));
_channel.connect(3000);
LastLogin = _reader.readLine(); //get last login message
}//try to connect
catch (JSchException ex)
{
throw ex;
}
catch (UnsupportedEncodingException uee)
{
return false;
}
catch (IOException ioe)
{
return false;
}
return true;
}
Here is my execute method. I know there is a better way to get from the char[] to an ArrayList but I haven't ironed that out just yet.
public List<String> ExecuteCommand (String command)
{
List<String> returns = new ArrayList();
try {
_writer.write(command);
if ( !command.endsWith("\n") )
_writer.write("\n");
_writer.flush();
Thread.sleep(2000); //allow time to exec
int c;
StringBuilder response= new StringBuilder();
while (_reader.ready()) {
c = _reader.read();
if (c == -1)
break;
response.append( (char)c ) ;
}//while
String[] lines = response.toString().split("\n");
for (String line: lines)
{
if (line.trim().length()!=0)
returns.add(line);
}
}//try
catch (IOException e)
{
//handle this later
}//catch
catch (InterruptedException ie)
{
//handle this later
}
return returns;
}//ExecuteCommand
I know it isn't great but it works.
I am trying to send a file from server side to client side upon request. The file that is sent is encrypted and the client shpuld decrypt it. the encryption process works fine but while decrypting i need to have the DerIOBuffer objetc which I have using serializing. what should i do..please help
server:
import java.net.*;
import java.io.*;
import java.math.BigInteger;
import com.dragongate_technologies.borZoi.*;
public class FileServer {
static final int LISTENING_PORT = 3210;
public static void main(String[] args) {
File directory; // The directory from which the gets the files that it serves.
ServerSocket listener; // Listens for connection requests.
Socket connection; // A socket for communicating with a client.
/* Check that there is a command-line argument.
If not, print a usage message and end. */
if (args.length == 0) {
System.out.println("Usage: java FileServer <directory>");
return;
}
/* Get the directory name from the command line, and make
it into a file object. Check that the file exists and
is in fact a directory. */
directory = new File(args[0]);
if ( ! directory.exists() ) {
System.out.println("Specified directory does not exist.");
return;
}
if (! directory.isDirectory() ) {
System.out.println("The specified file is not a directory.");
return;
}
/* Listen for connection requests from clients. For
each connection, create a separate Thread of type
ConnectionHandler to process it. The ConnectionHandler
class is defined below. The server runs until the
program is terminated, for example by a CONTROL-C. */
try {
listener = new ServerSocket(LISTENING_PORT);
System.out.println("Listening on port " + LISTENING_PORT);
while (true) {
connection = listener.accept();
new ConnectionHandler(directory,connection);
}
}
catch (Exception e) {
System.out.println("Server shut down unexpectedly.");
System.out.println("Error: " + e);
return;
}
} // end main()
static class ConnectionHandler extends Thread {
// An object of this class is a thread that will
// process the connection with one client. The
// thread starts itself in the constructor.
File directory; // The directory from which files are served
Socket connection; // A connection to the client.
TextReader incoming; // For reading data from the client.
PrintWriter outgoing; // For transmitting data to the client.
ConnectionHandler(File dir, Socket conn) {
// Constructor. Record the connection and
// the directory and start the thread running.
directory = dir;
connection = conn;
start();
}
void sendIndex() throws Exception {
// This is called by the run() method in response
// to an "index" command. Send the list of files
// in the directory.
String[] fileList = directory.list();
for (int i = 0; i < fileList.length; i++)
outgoing.println(fileList[i]);
outgoing.flush();
outgoing.close();
if (outgoing.checkError())
throw new Exception("Error while transmitting data.");
}
void ecies_ex(String fileName) throws Exception {
// This function encrypts the file that has been requested
// by the client.
String at1,dc1,der1;
OutputStream os = connection.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
ECDomainParameters dp = ECDomainParameters.NIST_B_163();
ECPrivKey skA = new ECPrivKey(dp, BigInteger.valueOf(123));
ECPubKey pkA = new ECPubKey(skA);
ECPrivKey skB = new ECPrivKey(dp, BigInteger.valueOf(230));
ECPubKey pkB = new ECPubKey(skB);
File file = new File(directory,fileName);
if ( (! file.exists()) || file.isDirectory()) {
// (Note: Don't try to send a directory, which
// shouldn't be there anyway.)
outgoing.println("error");
}
else {
outgoing.println("ok");
String pt1 = new String();
BufferedReader br = null;
try {
String sCurrentLine;
br = new BufferedReader(new FileReader(fileName));
while ((sCurrentLine = br.readLine()) != null) {
pt1=pt1+"\n"+sCurrentLine;
}
} catch (IOException e) {
e.printStackTrace();
}
ECIES crypt = new ECIES(skA, pkB, pt1.getBytes()); // encrypt the data
try {
DerIOBuffer der = new DerIOBuffer(crypt);
oos.writeObject(der);
ECIES decrypt = der.toECIES();
dc1=decrypt.toString2(); //cipher text
//at1=decrypt.toString3(); //authentication tag
FileWriter fstream = new FileWriter("encrypted.txt");
BufferedWriter out = new BufferedWriter(fstream);
out.write(dc1);
//Close the output stream
out.close();
} catch (Exception e) {
System.out.println(e.toString());
}
TextReader fileIn = new TextReader( new FileReader("encrypted.txt") );
while (fileIn.peek() != '\0') {
// Read and send lines from the file until
// an end-of-file is encountered.
String line = fileIn.getln();
outgoing.println(line);
}
}
outgoing.flush();
// oos.close();
// os.close();
outgoing.close();
if (outgoing.checkError())
throw new Exception("Error while transmitting data.");
}
public void run() {
// This is the method that is executed by the thread.
// It creates streams for communicating with the client,
// reads a command from the client, and carries out that
// command. The connection is logged to standard output.
// An output beginning with ERROR indicates that a network
// error occurred. A line beginning with OK means that
// there was no network error, but does not imply that the
// command from the client was a legal command.
String command = "Command not read";
try {
incoming = new TextReader( connection.getInputStream() );
outgoing = new PrintWriter( connection.getOutputStream() );
command = incoming.getln();
if (command.equals("index")) {
sendIndex();
}
else if (command.startsWith("get")){
String fileName = command.substring(3).trim();
ecies_ex(fileName);
//sendFile(fileName);
}
else {
outgoing.println("unknown command");
outgoing.flush();
}
System.out.println("OK " + connection.getInetAddress()
+ " " + command);
}
catch (Exception e) {
System.out.println("ERROR " + connection.getInetAddress()
+ " " + command + " " + e);
}
finally {
try {
connection.close();
}
catch (IOException e) {
}
}
}
} // end nested class ConnectionHandler
} //end class FileServer
client :
import java.net.*;
import java.io.*;
import java.math.BigInteger;
import com.dragongate_technologies.borZoi.*;
public class FileClient {
static final int LISTENING_PORT = 3210;
public static void main(String[] args) {
String computer; // Name or IP address of server.
Socket connection; // A socket for communicating with that computer.
PrintWriter outgoing; // Stream for sending a command to the server.
TextReader incoming; // Stream for reading data from the connection.
String command; // Command to send to the server.
String pt3;
ECDomainParameters dp = ECDomainParameters.NIST_B_163();
ECPrivKey skB = new ECPrivKey(dp, BigInteger.valueOf(230));
//ECPrivKey skB = new ECPrivKey (dp);
ECPubKey pkB = new ECPubKey(skB);
/* Check that the number of command-line arguments is legal.
If not, print a usage message and end. */
if (args.length == 0 || args.length > 3) {
System.out.println("Usage: java FileClient <server>");
System.out.println(" or java FileClient <server> <file>");
System.out.println(" or java FileClient <server> <file> <local-file>");
return;
}
/* Get the server name and the message to send to the server. */
computer = args[0];
if (args.length == 1)
command = "index";
else
command = "get " + args[1];
/* Make the connection and open streams for communication.
Send the command to the server. If something fails
during this process, print an error message and end. */
try {
connection = new Socket( computer, LISTENING_PORT );
incoming = new TextReader( connection.getInputStream() );
outgoing = new PrintWriter( connection.getOutputStream() );
outgoing.println(command);
outgoing.flush();
}
catch (Exception e) {
System.out.println(
"Can't make connection to server at \"" + args[0] + "\".");
System.out.println("Error: " + e);
return;
}
/* Read and process the server's response to the command. */
try {
if (args.length == 1) {
// The command was "index". Read and display lines
// from the server until the end-of-stream is reached.
System.out.println("File list from server:");
while (incoming.eof() == false) {
String line = incoming.getln();
System.out.println(" " + line);
}
}
else {
// The command was "get <file-name>". Read the server's
// response message. If the message is "ok", get the file.
String message = incoming.getln();
if (! message.equals("ok")) {
System.out.println("File not found on server.");
return;
}
PrintWriter fileOut; // For writing the received data to a file.
if (args.length == 3) {
// Use the third parameter as a file name.
fileOut = new PrintWriter( new FileWriter(args[2]) );
}
else {
// Use the second parameter as a file name,
// but don't replace an existing file.
File file = new File(args[1]);
if (file.exists()) {
System.out.println("A file with that name already exists.");
System.out.println("To replace it, use the three-argument");
System.out.println("version of the command.");
return;
}
fileOut = new PrintWriter( new FileWriter(args[1]) );
}
while (incoming.peek() != '\0') {
// Copy lines from incoming to the file until
// the end of the incoming stream is encountered.
String line = incoming.getln();
fileOut.println(line);
}
InputStream is = connection.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
DerIOBuffer der = (DerIOBuffer)ois.readObject();
ECIES decrypt = der.toECIES();
byte[] pt2 = decrypt.decrypt(skB); // decrypt the data
pt3=new String(pt2);
if (fileOut.checkError()) {
System.out.println("Some error occurred while writing the file.");
System.out.println("Output file might be empty or incomplete.");
}
}
}
catch (Exception e) {
System.out.println("Sorry, an error occurred while reading data from the server.");
System.out.println("Error: " + e);
}
} // end main()
} //end class FileClient
If you care about errors, you should not use PrintWriter. Why? Because if an error does occur on output via a PrintWriter, you have no way to find out what it was. This is what makes it difficult to figure out what the real problem is in this case. I recommend that you fix this so that you can get to the real cause of the problem.
The real problem could be related to to the following issues:
If the stuff you are trying to write could be binary, you shouldn't use PrintWriter ... or Readers / Writers at all.
You seem to be using Object serialization unnecessarily ... and on a class that looks like it may not be serializable.
Based on the difficulty I had in finding documentation for the "borZoi" library ... and other things ... I think you may have made a poor choice of library for doing crypto work.