• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

How do I read the data from a telnet connection without waiting for the connection to end?

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm a web developer that works primarily in cfml (ColdFusion and Lucee), which is a tag based server side language.  Because both of these servers are built upon java, I'm able to use java when necessary, but I have nearly zero knowledge or experience with it.  Unfortunately, nothing in cfml seems to handle telnet at all, and I am trying to write a script to interact with a game server that can only be done over telnet, so into the java I go...

With the help of chatGPT I have cobbled together three cfml functions that use Apache Commons Net to initiate a telnet session.  My functions look like this:



What I'm trying to accomplish is to establish a connection to the game server and send commands.  I will also need to be able to read what the game server sends back.

The above code seems to work to establish the telnet connection and to close it; I can see that on the console of the game server.  However, I don't understand how to read the output of that session and I think my code is all wrong there.  Line 62-87 is what I'm primarily looking for help with here (I provided the rest for context).

When I call the read function I get back nothing but a number, such as 13.  If I call the read function twice it hangs the server until a timeout occurs.  ChatGPT has been no help here and I feel like I'm banging my head against the wall.

Can someone please give me some direction as to what I want to do in the telnetRead function?  Any suggestions would be really appreciated.
 
Saloon Keeper
Posts: 10930
87
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It's hard  to tell what parts are actual Java. "NEQ" is obviously not but it's in the middle of stuff that could be. I don't see you closing BufferedReader anywhere, that could be leaving a resource open.
 
Saloon Keeper
Posts: 28321
210
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
wow. I though ColdFusion was long, long dead.

Item #1. Putting logic in your markup is generally considered to be a Very Bad Idea. Whether it's Java Scriptlets, PHP, or whatever, separating the presentation from the processing is almost always going to make your life simpler. Since you're using a JVM-based engine, see if you can't push the code into a Java class, instead and let the cfm tags invoke that the way that JavaServer Pages (JSPs) use Exression Language (EL). If Java doesn't appeal, maybe another JVM-based language such as Kotlin or Jython might work.

Item #2. Be sure know where the request is coming from. If you want the backend JVM to do the telnet-talking, the above applies. If you need the remote client to make the connection, you might do better to code in JavaScript.

Item #3. If you want full interactivity you need unbuffered I/O. telnet was designed (as its name implies) to emulate a TeleType machine and TTYs worked with single character transmissions, not packets.

Item #4. Don't forget that telnet has crap security and transmits unencrypted. Don't use it if Bad Things can be done with the Telnet client. If they can, keep the telnet behind a firewall, over an encrypted VPN, use SSH, or at least something.  
 
Marshal
Posts: 79971
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the Ranch

I don't think this is a “beginning Java®” question, so I shall try moving you to our IO forum.
 
Nicholas Bostaph
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you for the responses!


Tim Holloway wrote:
Item #3. If you want full interactivity you need unbuffered I/O. telnet was designed (as its name implies) to emulate a TeleType machine and TTYs worked with single character transmissions, not packets.



Ah, so when I call java.io.BufferedReader on line 67 I'm heading down the wrong path already, and that is waiting for some kind of stop command or for the buffer to fill before continuing?  Google indicates there is no such thing as UnbufferedReader; could you point me to the right subclass to use in its place?  Would InputStreamReader (https://docs.oracle.com/javase%2F8%2Fdocs%2Fapi%2F%2F/java/io/InputStreamReader.html) be the right approach?

Tim Holloway wrote:
Item #4. Don't forget that telnet has crap security and transmits unencrypted. Don't use it if Bad Things can be done with the Telnet client. If they can, keep the telnet behind a firewall, over an encrypted VPN, use SSH, or at least something.  



Unfortunately, this is the only way that is supported to send commands to the game server.
 
Sheriff
Posts: 28329
97
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yeah, you won't want buffering for a Telnet conversation.  But you do want a Reader and not a Stream, so InputStreamReader will work just fine. (The remark in the docs about "efficiency" isn't aimed at you. Ignore it.)
 
Tim Holloway
Saloon Keeper
Posts: 28321
210
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Looks like my earlier response failed to post. Paul said much the same thing but I should add that in a Unix/Linux system, you may also need to "stty" the serial device you're talking over as otherwise the OS itself may buffer.
 
Nicholas Bostaph
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you for pointing me in the right direction!

I've managed to cobble together an extremely messy, but working cfc for communicating with a telnet server.  Still much cleanup to do, but for anyone else who is trying to do this and happens across this thread, here is the PoC:

 
Master Rancher
Posts: 5060
81
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm glad you have something working, at least somewhat.  I don't follow all the ColdFusion stuff very well, so I haven't looked super carefully at what you have now.  But, I'm thinking the BufferedReader solution probably wasn't so far off.  I suspect the main problem was around here:

The problem was that if the server is waiting for a command from you (before writing at least five lines), then it's stuck waiting forever.  Probably you need to check, after each individual line is read, does that line require some sort of response from you?  If so, call some other code to do whatever needs to be done, before continuing the loop to read the next line.

There are potentially some situations where a BufferedReader and readLine() won't work for you.  But in many cases, it will.  You need to look at: how does the sequence of commands and responses work?  How does one side know when it needs to do something?  Many common protocols are line-based, meaning that once you start reading one character, you can safely continue reading until you've read a whole line, at least, before you might need to send any response.  If that's the case, then BufferedReader and readLine() will work find for you.  However, if you ever need to send a response at a point where you have not received a new line (e.g. if you need to report improper spelling in a sentence which is not yet finished with a "return"), then a line-based solution using readLine() will not work for you.  In that case you need to read the individual characters, and decide after each character whether something has occurred that requires a response from you.  

But, a readLine() solution will probably be simpler, if the protocol allows it.  The good news is, many protocols do.  And it looks like yours does too, based on what I can discern about your code that checks for chr(13), a carriage return.  You're looking for new lines and reacting to those.  Great - chances are, you can use a BufferedReader / readLine() solution that will be cleaner to work with.   Enjoy!
 
it's a teeny, tiny, wafer thin ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic