Telnet basic IO operations - java

I'm trying to create a simple library (hope to share it with the world) that will allow to send and receive commands to remote equipment via telnet.
I'm trying to keep the code as simple as possible and it's already working, but I can't seem to understand how the input stream is working;
I'm reading each line separately and normally input should stop at input "Username:" after which I should type in my username.
What actually happens is that after I detect that I've received this line and send a response it is already too late (new input has already been received).
Any idea how a telnet session actually works and how the last command (after which the remote equipment waits) is received?
import java.util.*;
import java.io.*;
import java.net.*;
public class telnet {
public static void main(String[] args){
try{
//socket and buffer allocation
Scanner scan = new Scanner (System.in);
Socket socket = null;
PrintWriter out;
BufferedReader in;
String input; // temp input
String input1="";
String buff = ""; // holds all the input
//socket and IO initialization
socket = new Socket("10.10.10.2", 23);
out = new PrintWriter(socket.getOutputStream(),true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
int i=0;
int j=0;
while(true){
input = in.readLine(); //printout given line
System.out.println("line "+i+":\n"+input);
if (input.contains("Username")){ //if reading 'username' send response
System.out.println("!got Username");
out.println("user");
continue;
}
if (input1.contentEquals(input)){ //if input is the same wait once then send ENTER
if (j==0){
System.out.println("!read same line. wait for new");
i++; j++;
continue;
}
else{
System.out.println("!no new line. sending ENTER");
out.println("\r");
i++;j=0;
}
} else {j=0;}
input1=""; //copy input to temp string to check if same line or new
input1.concat(input);
i++;
if (i==20) break;
}
//CLOSE
out.close();
in.close();
socket.close();
} catch(IOException e){}
}
}

A telnet server and telnet client don't just send plain text back and forth. There is a telnet protocol, and both the client and server can send commands to each other. The telnet server that you are connecting to may be trying to negotiate some setting change with your program, and your program may be interpreting the byte stream as lines of text.
The standard Unix telnet client program will suppress using the telnet protocol when it's not talking to an actual telnet server. Instead, it will fall back to sending text line-by-line and printing anything received from the server. This allows the program to be used to communicate with SMTP servers, HTTP servers, and the like. The telnet server doesn't necessarily have this fallback behavior; it may always assume that the client implements the protocol.

Related

Why server side socket is not receiving messages after reading "\n.\n"

I have written simple java client/server program and client is trying to sent like below:
os = new DataOutputStream(socket.getOutputStream());
os.writeBytes("HELO\n");
os.writeBytes("MAIL From: person#example.com\n");
os.writeBytes("RCPT To: to#example.com\n");
os.writeBytes("DATA\n");
os.writeBytes("From: person#example.com\n");
os.writeBytes("Subject: testing\n");
os.writeBytes("Hi there\n"); // message body
os.writeBytes("\n.\n");
os.writeBytes("QUIT");
But my server side socket is able to read upto "\n." and then it is waiting to read.
Why is it not reading "QUIT" message after "\n.\n"
Server code:
clientSocket = echoServer.accept();
is = new DataInputStream(clientSocket.getInputStream());
os = new PrintStream(clientSocket.getOutputStream());
// As long as we receive data, echo that data back to the client.
while (true) {
line = is.readLine();
os.println(line);
}
You need to put a "\n" after QUIT, the stream is reading QUIT, but it doesn't cause the is.readLine() because theres no "new line" character in the string

Chat: Sending message to all clients on a server

I have a server-client application set. (HOMEWORK)
So far I have figured out how to have multiple clients connect to the server and have the server aggregate the messages the clients send, as well as having the server send the client's message back to the client and displaying it in the chat pane.
My issue is trying to send a message to multiple clients. I am only allowed to use ServerSocket and Socket libraries.
Say I have 2 clients connected to the server. One client sends a message, the message is displayed in the client's chat. The second client sends a message, the first client does NOT receive it, and the second client's chat window displays the first client's message.
Essentially the server is sending the most recent message that the respective client has not displayed in the chatbox, and I have no idea why or how.
Code for server-to-client communication :
Class CommunicationThread extends Thread {
//Vector containing all client sockets currently connected
//Held offsite, here for clarity
public Vector<Socket> socketVector;
public CommunicationThread (Socket clientSoc, Server ec3, Vector<Socket>socketVectorg)
{
//add new socket to vector, start thread
clientSocket = clientSoc;
socketVectorg.add(clientSocket);
this.socketVector = socketVectorg;
gui = ec3;
}
public void run()
{
System.out.println ("New Communication Thread Started");
try {
//Client's chat box (output)
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),
true);
//Input line from client
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("Server: " + inputLine);
gui.history.insert(inputLine + "\n", 0);
//*************HERE IS MY ISSUE*******************
for(Socket s : socketVector){
out = new PrintWriter(s.getOutputStream(),
true);
out.println(inputLine);
}
if (inputLine.equals("Bye."))
break;
if (inputLine.equals("End Server."))
gui.serverContinue = false;
}
out.close();
in.close();
clientSocket.close();
}
catch (IOException e)
{
System.err.println("Problem with Communication Server");
//System.exit(1);
}
}
}
I know I am overwriting "out" but I don't think that is my issue so it is in my code while I am testing.
My issue is marked in the code above. The vector accurately stores the socket ID, and since I am creating a new PrinterWriter based on the vector, I would only assume that it would get the output field of the respective client, but it does not.
My intuition is that it is a problem with threading or closing the output, but I honestly don't know.
Any recommendations are appreciated.
Your problem it seems to me is that you want to do the input and output work on the client socket all in the same place, and there's no need for that. The client socket's output stream can be written to in the GUI thread, and all in one place. You can keep a collection of the output streams if need be and when you want to reply to all, iterate through the collection (probably a HashMap<String, OutpuStream> where the String is some client identifier) and send the messages.

TelnetClient java stream

TelnetClient telnet = new TelnetClient();
telnet.connect( "192.168.0.6", 23 );
PrintWriter out =
new PrintWriter(telnet.getOutputStream(), true);
DataInputStream in =
new DataInputStream(telnet.getInputStream());
BufferedReader stdIn =
new BufferedReader(
new InputStreamReader(System.in));
String userInput;
byte buffer[] = new byte[1024];
int bytesRead;
while ((bytesRead=in.read(buffer,0,1024)) != -1) { // read from server
System.out.print(new String(buffer, 0, bytesRead, "UTF-8"));
userInput = stdIn.readLine();
if (userInput != null) {
out.println(userInput);
out.flush();
}
}
telnet.disconnect();
Hello I have a problem with this program during the connection to the server.
This program should allow me to start a telnet connection to a server and send to it some commands and return me the result of these but when I start the connection some times it return me only the HELLO of the server (Welcome to Microsoft Telnet Service) and not the entire message including LOGIN:
When I send commands the response of these is delayed.
For example i write "DIR" and the response is written only when I press enter two times...
Where I wrong? Please help me.
When trying to connect to network services using such protocol (Telnet, FTP ,SSH ..) which are session based protocol and require to keep your connection alive and be interactive with the service , it's recommended to use available Java API instead of reinventing the wheel (only if you are asked to do without a third party library), in your case you can use Apache Common Net wich provide a set of helpful features to connect to servers using many network protocols including Telnet .

Client-Server Socket: Not reaching if statement [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why isn't my application entering my if statement
I'm trying to write a console client-server application in Java; using sockets, I currently have a simple login system and a simple command system. The login system appears to work, and the connection seems to be working.
However, the command system does not seem to function at all, when the command is received by the server, it does not appear to send anything back.
So my main question is why doesn't my server send anything back to the client when the command is received?
Here is my Server:
import java.io.*;
import java.net.*;
class TCPServer2
{
public static void main(String argv[]) throws Exception
{
//error is caused by command being used differently to login & username/password strings.
//consider removing command as a set string and adding a statement which takes
//the readLine value, adds it to a string and the command is the value of said string.
//If string is = "listLanguages" do this else if = "getcost" do this else "invalid cmd".
ServerSocket welcomeSocket = new ServerSocket(6789);
Map<String, String> userDetails = new HashMap<String, String>();
userDetails.put("JOHN","UNCP");
userDetails.put("MATT","UNCP");
String Command;
String username;
String username1;
String password;
String password1;
String cmd;
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
username = inFromClient.readLine();
System.out.println("\nUsername received: " + username);
password = inFromClient.readLine();
System.out.println("\nPassword received: " + password);
username1=username.toUpperCase();
password1=password.toUpperCase();
if (userDetails.get(username1).equals(password1))
{
outToClient.writeBytes("Hello " + username1);
outToClient.writeBytes("\nOther users registered on the server currently include: \n");
for (String str : userDetails.keySet())
{
outToClient.writeBytes(str);
}
}
else
{
outToClient.writeBytes("Invalid Username and/or password.\n");
}
BufferedReader inFromClient2 =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient2 = new DataOutputStream(connectionSocket.getOutputStream());
Command = inFromClient2.readLine();
System.out.println("\nCommand received: " + Command);
if(Command.equals("listTranslations"))
{
outToClient2.writeBytes("English,Thai,Geordie,etc.");
}
else
{
if(Command.equals("getCost"))
{
outToClient2.writeBytes("£100\n");
}
else
{
outToClient2.writeBytes("Invalid Command");
}
}
}
}
}
Here is my client:
import java.io.*;
import java.net.*;
class TCPClient2
{
public static void main(String argv[]) throws Exception
{
String userName;
String passWord;
String loginInfo;
String loginInfo2;
String loginInfo3;
String command;
String commandInfo;
String commandInfo2;
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.out.println("Username: ");
userName = inFromUser.readLine();
outToServer.writeBytes(userName + "\n");
System.out.println("Password: ");
passWord = inFromUser.readLine();
outToServer.writeBytes(passWord + "\n");
loginInfo = inFromServer.readLine();
System.out.println(loginInfo);
loginInfo2 = inFromServer.readLine();
System.out.println(loginInfo2);
loginInfo3 = inFromServer.readLine();
System.out.println(loginInfo3);
System.out.println("Please enter a command: ");
command = inFromUser.readLine();
outToServer.writeBytes(command);
commandInfo = inFromServer.readLine();
System.out.println(commandInfo);
commandInfo2 = inFromServer.readLine();
System.out.println(commandInfo);
clientSocket.close();
}
}
Here's how it's supposed to work:
The client connects to the server,
The client asks user to login,
The user inputs his login info,
The server checks the login info,
The server tells the client it's logged in successfully,
The client asks the user to input a command,
The user inputs a command (to request a price),
The command is sent to the server,
The server sends back the desired in info,
It should then loop back to the user being asked to input a command.
However, it does not do this. It gets stuck after the user logs in, on the "Other users registered on the server currently include:" line, without printing any data.
Why is it doing this?
Why it's getting stuck is probably because both client and server are on a readLine() resulting in a deadlock. Client waits for incomming data and so is the server, Since this is a command promt client and server, and you have no "button" to send the data with.
I would add info showing which variable it is printing at the moment so you can easily follow where it gets stuck. Example:
loginInfo = inFromServer.readLine();
System.out.println("loginInfo client Side "+loginInfo);
This will show you that it's printing the loginInfo variable located in the client. Now you can easily follow the flows and locate where it's going wrong.
I've never done a command promt server/client (only gui), but when you are printing your list of users with your current design, you might want to to build a string with all usernames, send the whole string over to the client, and then the client separates the string with StringBuilder and prints the result. This is because the client will not know how many "usernames" the server will send
Have you tried flushing the buffer of the data output stream writer before you send the next line. I'm also curious why you use two different data output stream writers and input stream readers for one client. Couldn't you just use the same ones for both parts of your program.
The issue is with improper socket data read/write methods. You have to always flush() when you are writing data to sockets. If you comment line
//loginInfo3 = inFromServer.readLine();
//System.out.println(loginInfo3);
Then you can see that the client displays the "Please enter a command" but after you enter the command the socket is not flushed/closed so the server keeps waiting.
The main issue with the Server and Client code is proper hand shake. You have to write code in a block, open socket, write command, get response and close socket. This should be a common way of entering the data. You have clubbed sockets and writing data to the streams without proper flush/close, hence it is waiting at different points.

buffered reader not receiving data from socket

I am writing a client application that will receive a continuous flow of data through tcp/ip. The problem I'm having is that the buffered reader object isn't receiving any data and is hanging at the readline method.
The way the server works is that you connect to it, and then send authentication information in order to receive data. The gist of my code is below
socket = new Socket(strHost, port);
authenticate();
inStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
process(inStream);
authenticate()
{
PrintWriter pwriter = new PrintWriter(socket.getOutputStream(), true);
pwriter.println(authString);
}
process(BufferedReader bufferedReader)
{
while((line = bufferedReader.readLine()) != null)
dostuff
}
I created a sample server application that sends data the way (I think) the server is sending data and it connects, and receives and processes the data fine. I can connect to the server fine in my application. I can also telnet to the server and write the authentication string and receive a flood of data using telnet. However my application just hangs at readLine with the server and I'm out of idea's why.
The data coming in (through telnet atleast) looks like a continuous stream of the following:
data;data;data;data;data
data;data;data;data;data
Why is my app hanging at readline, am I not outputting the authentication line correctly? I'm not receiving any errors...
EDIT
My sample server code (which is working correctly)...again this is only mimicking the way I think the real server is running but I can connect to both in my application just not receive data from the real server.
public static void main(String[] args) throws IOException
{
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(1987);
}
catch (IOException e)
{
System.out.println("Couldn't listen on port: 1987");
System.exit(-1);
}
Socket clientSocket = null;
try
{
clientSocket = serverSocket.accept();
}
catch (IOException e) {
System.out.println("Accept failed: 1987");
System.exit(-1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String something;
while ((something = in.readLine()) != null)
{
while(true)
{
out.println(message);
}
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
Firstly you should call BufferedReader.ready() before calling readLine(), as the ready() will tell you if it's ok to read.
PrintWriter doesn't throw I/O Exception so the write may have failed without your knowledge which is why there is nothing to read. Use PrintWriter.checkError() to see if anything as gone wrong during the write.
You ought to set up the input and output streams on the Socket at the same time before you write anything down the pipe. If your reader is not ready when the other end tries to write you will get a broken pipe in the server and it won't send any more data. Telnet sets up read and write before you have written or read anything.
You can make use of Wireshark to tell if the server is actually sending data.
BufferdReader.readLine() reads lines, i.e. sequences of characters ended with \r or \r\n. I guess that your server writes its output into one single line. Your telnet output proves this assumption. Just use PrintWriter.println() at server side.
this work with me
with socket without flush
void start_listen()
{
String result1="";
char[] incoming = new char[1024];
while (!s.isClosed())
{
try {
int lenght = input.read(incoming);
result1 = String.copyValueOf(incoming,0,lenght);
}
catch (IOException e)
{
e.printStackTrace();
}
Log.d("ddddddddddd",result1);
}

Categories