I'm writing a ServerSocket in java. I want to send some special content to client connecting to me through telnet. I want to send other content if he/she connects through Browser and etc. Is there any way to find out that user is connecting to me with telnet?
My code :
public void handleConnection(Socket socket) throws IOException {
String author = "Ehsan Akbari";
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
if(checkoutClientType(socket)=="telnet")
out.println("You are connecting through telnet :\)");
else
out.println("You are not connecting through telnet :|");
}
What should be the definition of checkoutClientType(Socket s);?
You cannot tell what program is on the other side of a socket by examining the socket itself. There is no test or operation you can perform on the socket that will distinguish the client program.
The only hope is to examine the data being transmitted to see if it matches an expected pattern, but for that you have to have some data transmitted. It might be possible to tell if the remote is telnet if you were to send a Telnet Protocol command such as AYT (Are You There), but that would probably not sit well with a different client such as a browser.
If you were able to proxy the data between the client and a handling process or thread and examine it you might be able to eventually determine if it was Telnet, but probably not, and probably not immediately.
Related
I created application in android studio and server in python and I want to connect the client to my server with one socket per client so that I don't need to close the socket and I could send data from the server to any connected client I want.
My server is multi-threaded and it working only if I'm closing every socket after sending data back.
At my java app I created class that contain socket object and methods to contact with the server and I think that my problem is at this method:
private static String getMessageFromServer() throws IOException {
in = new InputStreamReader(sock.getInputStream());
bf = new BufferedReader(in);
return bf.readLine();
}
As you can see this method reads data from the server and the problem is that it keep reading data until the server close the socket, so I'm asking if there is any option to read data from server and stop the reading after I already got the data and without the server closes the socket?
Thanks :-)
I'm a novice in Java socket communication, I'm trying to connect 3 clients to a server without the use of threads as the number of clients connected to the server will as be 3. I have written a condition in the server to tokenize the received input from the client and send write to the respective stream. But the message isn't reaching the server so I'm not sure whether the client isn't writing to the stream or the server is unable to receive the data. I'm trying to establish a cryptographic protocol between the connected clients for demonstration purposes.
I was using BufferedReader and PrintStream earlier since I was testing with keyboard input, then I changed to data streams still doesn't seem to work
Here my code at Server.java to forward messages, the control doesn't appear to come to this loop at all(not sure).
while(true){
String recvd=cin2.readLine();
System.out.println("At server: "+recvd);
StringTokenizer st = new StringTokenizer(recvd);
String MsgToSend=st.nextToken();
String recipient=st.nextToken();
if(recipient.equalsIgnoreCase("client1")){
cout2.writeUTF(MsgToSend);
}
else if(recipient.equalsIgnoreCase("client2")){
cout.writeUTF(MsgToSend);
}
else if(recipient.equalsIgnoreCase("client3")){
cout3.writeUTF(MsgToSend);
}
}
Here is my client-side code,
while(i==0){
String s1="A";
String s2="B";
String s3="client1";
String toSend=String.join(" ",s1+s2,s3);
System.out.println("toSend :"+toSend);
sout.writeUTF(toSend);
sout.flush();
i++;
}
Receiving Client,
while (true){
s=sin.readLine();
System.out.print("Server : "+s+"\n");
}
Not sure whether the client is unable to write or the server is unable to read. Any suggestions or solutions to correct the code?
The socket navigation logic in your server file seems to be strange as you are manually creating a string with keyword client1 and then tokenizing it for navigation. By this approach your flow would get static and establishment of a protocol gets difficult.
Please see:
You are sending the data to client 1 by forming the string AB client1, then your server file's first line is using client 2 socket reading. (Sending data from client1 socket to client1 socket, not right).
Please change that to client1 socket reading, use prinln() and readline() to send and read socket data and then check if your flow is fine!
Also, for the protocol flow, you have to send the data to the other two sockets and not to the one that is sending.
For eg: if you are sending the data from client 1 to client 2, as per your approach, you have to for a string AB client2 and send to the server, tokenize it and navigate the flow to client 2.
Hope this helps!
Thanks,
Areed
I am currently trying to make an application that will send messages to a server using one port, but will receive messages on another port. However, based on tutorials I have followed, it looks like the act of connecting to the server is where ports come into play and my client is receiving and sending messages on the same port. How do I make it so it sends on one port but receives on the other?
Here is the code that I think is relevant from the client side (I put some stuff that seems unrelated because I think they are things that would be altered by receiving on one port but sending on another, and ignore the comment about replacing inetaddress, that is just me working on implementing this in a gui):
public void startRunning(){
try{
connectToServer();
setupStreams();
whileChatting();
}catch(EOFException eofException){
showMessage("\n Client terminated connection");
}catch(IOException ioException){
ioException.printStackTrace();
}finally{
closeStuff();
}
}
//connect to server
private void connectToServer() throws IOException{
showMessage("Attempting connection... \n");
connection = new Socket(InetAddress.getByName(serverIP), 480);//replace serverIP with ipTextField.getText or set serverIP to equal ipTextField.getText? Same with port number.
showMessage("Connected to: " + connection.getInetAddress().getHostName() );
}
//set up streams to send and receive messages
private void setupStreams() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
showMessage("\n Streams are good! \n");
}
//while talking with server
private void whileChatting() throws IOException{
ableToType(true);
do{
try{
message = (String) input.readObject();
showMessage("\n" + message);
}catch(ClassNotFoundException classNotfoundException){
showMessage("\n Don't know that object type");
}
}while(!message.equals("SERVER - END"));
}
//send messages to server
private void sendMessage(String message){
try{
output.writeObject("CLIENT - " + message);
output.flush();
showMessage("\nCLIENT - " + message);
}catch(IOException ioException){
messageWindow.append("\n something messed up ");
}
}
//change/update message window
private void showMessage(final String m){
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
messageWindow.append(m);
}
}
);
}
EDIT/UPDATE: To help clarify some things, here is some more information. The device that sends the first message is connected to a sensor, and it sends information when that sensor detects something to the other device. The receiving device sends a message back on a different port telling the original sending device how to respond. Lets name these two devices the "reporter-action taker" and the "decision maker-commander".
If you want to use TCP/IP sockets you can't use a a socket to send and another to read. That's not what they are for.
If you use a centralized distributed algorithm (server/client communication) you have to set the server to listen on a single socket port with the ServerSocket class: then the server tries to accept clients through that socket.
Example:
ServerSocket listener = new ServerSocket(Port)
While (true) {
new Clienthandler(listener.accept());
}
The server will listen on that port, and when a client tries to connect to that port if it is accepted the server launches its handler. On this handler constructor the Socket object used on the client is received on an argument and can then be used to get the writers and the readers. The reader on this handler class will be the writer on the client class and vice-versa, maybe that's what you were looking for.
Your question about using two ports in this manner is a bit strange. You state that you have a client and a server and that they should communicate on different ports.
Just to clarify picture the server as a hanging rack for jackets with several hooks in a row. Each port the server listened on represents a hook. When it comes to the client server relationship the client or jacket knows where to find its hook, however the hook is blind and have no idea where to find jackets.
Now, the client selects a port or a hook and connects to it. The connection is like a pipeline with two pipes. One for the client to deliver data to the server with and the other to send data from the server back to the client. When the connection is established data can be transferred both ways. This means that we only need one port open on the server to send data both from the client to the server and in the opposite direction.
The reason for only having one open port open on the server for the clients to connect to is that holding an open port for connections is hard to do on a regular client computer. The normal desktop user will be behind several firewalls blocking incoming connections. If that wasn't the case the client would probably be hacked senseless from malicious viruses.
Moving on with the two port solution we could not call this a client server connection per say. It would be more like a peer to peer connection or something like that. But if this is what you want to do, the application connecting first would have to start by telling the other application what ip and port to use for connecting back, it should probably also want to give some kind of token that are to be used to pair the new incoming connection when connecting back.
You should take note that making such an implementation is not a good idea most of the time as it complicates things a whole lot for simple data transfer between a client and server application.
I have two PCs in one network that I want to connect. One of them should send a notification to the other via TCP. One the one PC I have a "server" (Python script) socket which waits for the "client"(Jar file) to send a specific String and then it gives me a notification. This works perfectly fine when I'm trying it out one one PC. But when I want to do the intended action the "client" PC's .jar gives me an error that the connection is refused. Do I have to open a specific port on the other PC or what else could cause trouble? One PC runs Fedora the other Windows 8
"Server Code"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", 5005))
s.listen(1)
try:
while True:
komm, addr = s.accept()
while True:
data = komm.recv(1024)
if data == "$":
noty()
if not data:
komm.close()
break
finally:
s.close()
"Client" Code
public static void main(String[] args) throws Exception {
Socket socket = new Socket("192.168.178.25", 5005);
OutputStream out = socket.getOutputStream();
String dat = "$";
out.write(dat.getBytes());
socket.close();
}
Your server is probably binding to the wrong interface,
calling
s.bind(("", 5005))
Without setting an interface will allow the program to pick what ip address / interface it will connect to.
Since your client is trying to connect to ("192.168.178.25", 5005); you may want to put an IP address into the bind call to prevent the server picking the wrong ip interface.
Example:
s.bind(("192.168.178.25", 5005))
if its permission denied then something is blocking your connection with the computer. i would try to open a port and see if that works. if you want an example of java sockets you can take a look at my SUPER Tic-Tac-Toe Multiplayer it uses java sockets to send strings to the clients as a way to represent what actions the clients should take.
I would like to add the ability for users to telnet into my app where by they can type in commands etc. I would like a simple Java Telnet server whereby i can provide the authentication strategy.
By "telnet" i am not referring what lib provides telnet connectivity but something a little more. I want the boring protocol stuff done along with a shell that has hooks that i can use to process and execute command lines. Where or what these commands are, is of course my implementation.
This q is not about how to start a socket server or other protocol plumbing type.
In my experience, telnet is telnet, ssh is ssh... if you want the latter then you might look at something like: http://mina.apache.org/sshd/
I've never used it, though.
You could also use the native operating system SSH (if it has it) to tunnel and then run regular telnet on the server. Creating your own telnet access isn't at all complicated if it's just a custom command shell. And as the other poster mentions, there are libraries that make it easy.
...but ssh would be more secure and more straight-forward.
Telnet servers only do telnet.
You might find http://telnetd.sourceforge.net/ suitable.
"Target Audience:
Developers that want to integrate reasonable telnet access into their application."
What exactly do you mean by "telnet into my app where by they can type in commands etc."?
Since both telnet and ssh requires some application to run on the remote machine (most often an instance of a command shell), they really only provide the transport mechanism for the commands. Telnet in particular can be (and has been) abused to send general text-commands over a tcp connection. You can browse the web by using the command telnet www.target-domain.com 80 and manually enter all the http protocol stuff, but i wouldn't recommend it. ssh is just the same, although it adds ssl/tls security to the channel.
Therefore, what I guess you want is something like this:
import java.io.*;
import java.net.*;
public class telnettest {
public static void main(String[] args) throws IOException {
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
//Open a listening socket on port 8022 and wait for a connection
echoSocket = new ServerSocket(8022).accept();
System.out.println("connection established");
//Get input and output streams
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
} catch (IOException e) {
System.err.println("Couldn't get I/O for "
+ "the connection");
System.exit(1);
}
//Read lines from the input stream (corresponding to user commands)
String userInput;
while ((userInput = in.readLine()) != null) {
//For each line entered, just output it to both remote and local terminal
out.println("echo: " + userInput);
System.out.println("echo: " + userInput);
}
//Clean up connections.
out.close();
in.close();
echoSocket.close();
}
}
which is a shameless edit of this tutorial example.
I'm not sure about ssh login, but I suspect you could get there using javax.net.ssl.SSLServerSocket instead of ServerSocket.
What remains is to do something sensible with the user input, instead of just throwing it back in their faces.
Depeding on the amount of commands and their parameters, you can either do the command parsing yourself, or find a library that handles it for you.