This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

Determine if port on remote machine is live

Help for those learning Tcl or writing their own scripts.
Post Reply
n
na85
Voice
Posts: 5
Joined: Thu Jan 29, 2009 11:46 pm

Determine if port on remote machine is live

Post by na85 »

Hi guys.

I'd like my bot to be able to query a game server to see if it is online or not.

Basically, I want to do the following:

Code: Select all

open tcp connection with example.com on port 1234
IF server is alive
    return 1
ELSE
    return 0
The bot won't have to authenticate or any of that junk, all I want to know is if it gets a response from example.com on port 1234.

The documentation on the socket command is pretty vague and I'm fairly new to tcl scripting.

Is this even possible?
d
dj-zath
Op
Posts: 134
Joined: Sat Nov 15, 2008 6:49 am
Contact:

Post by dj-zath »

hi there!

I'm afraid its not going to be that easy to do (I'm sorta trying to do the same thing.. and having terrible luck with it..)

this example might work for you.. assuming a "proper" internet connection... (something MY ISP doesn't offer)..

Code: Select all


set T "30"
set IP "123.45.67.89"
set Port "8080"

if {(![info exists loop])}
     utimer $T [RunLoop1]
     set loop 1
}

proc  RunLoop1 {} {
     SockTest     
     utimer $T [list RunLoop1]
}

proc SockTest{} {
  if {([catch {set Sock [socket $IP $Port]}])} {
       putlog "Connection Not Present"
       return 0
  } else {
       close $Sock
       putlog "Connection Present"
       return 0
  }
}
The problem with the above example is your eggdrop might "freeze" while the connection is being tested.. depending on some situations (such as mine) this could become a problem..

the following might be better then:

Code: Select all

set IP "123.45.67.89"
set Port "8080"
set T "30"

if {(![info exists loop])}
     utimer $T [RunLoop1]
     set loop 1
}

proc  RunLoop1 {} {
     SockTest     
     utimer $T [list RunLoop1]
}

proc SockTest {} {
  if {([catch {set Sock [socket -async $IP $Port]; fconfigure $Sock -blocking 0;}])} {
       putlog "Connection Not Detected"
       return 0
  } else {
       close $Sock
       putlog "Connection Detected"
  }
}
NOTES:

IP = server/connection to be tested
Port = port of formentioned server
T = time in seconds to wait between test operations

CaSe CoUnTs! if you copy, copy carefully!

examples were derived from FreeBSD 6x (you may need to adjust the code for your particular OS/distro)

The above examples will test the presence of a connection... but under some situations, will NOT detect the presence of a remote host (such as, in my case, if the host's ISP proxies the connections!) in which case, it gets even MORE complecated and unreliable.. I'm STILL trying to resolve the issue of an infefinate lockup during handshaking.

My TCL coding skills are "old school".. and may be lacking newer techniques. Perhaps someone else can give ya something newer and better (assuming you have the latest versions on TCL and all nessessary packages installed/available on your shell/box.)

These examples are just "raw code" that addresses the connection-handling.. and doesn't include any actions such as what to DO with the tested resaults.. (it will NOT post to a chatroom, for example) The examples will post the resault to the log file.

the reason I didn't include "what to do", is because the orginating poster didn't specify what he wanted the result/outcome to be. the examples given will post the tested result to the log file.

I hope this helps... Good luck!

-DjZ-
:) :)
Last edited by dj-zath on Thu Mar 19, 2009 2:44 am, edited 1 time in total.
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Comments on the posted code:
First code works as intended. but will block until the connection is established, rejected, or timed out. During this time your eggdrop will be unable to take any other actions ("freze").

Secod code:
This code will always report that the remote host is availabe, regardless of the actual condition. The use of asynchronous connection here is improper.
dj-zath, you really must learn that having a valid socket handle does not corespond to having an established connection.
NML_375
d
dj-zath
Op
Posts: 134
Joined: Sat Nov 15, 2008 6:49 am
Contact:

Post by dj-zath »

nml375 wrote:dj-zath, you really must learn that having a valid socket handle does not corespond to having an established connection.
you are so right! :-) Although I do know the difference, I have been confusing them in my posts.. nml is correct that the 2nd code will report a live connection unless the LOCAL server cannot establish a socket handle (YES! I used the term CORRECTLY this time! YEY!).

That, there, was the ONE tiny piece of information I NEEDED to be told since the VERY begining.. which is the SOURCE of all my issues... But its more fun to tourment and school the fustrated, I guess <smirk>

I was trying to help the guy by giving him a straightforeward answer.. something I have yet to get! ah well.. :-)

But, I'm learning! :-)

After crashing my ISP's router a few times over all of this.. they have now capped me to 5G/month... how nice of them! so it really doesn't matter anymore.. thanks for trying anyways!

-DjZ-
:/ :/
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

dj-zath:
Regarding your other thread, I've been saying that (socket handle does not correspond to an established connection) numerous times. I've been trying to post a step-by-step explanation on how to establish the connection in a non-blocking manner (I believe this was your primary issue, as your eggdrop would "freeze").
I'm sorry to hear your ISP capped your network connection, but the only way I could imagine you'd be able to kill off routers like that, would be if you seriously hammered them.

na85:
The code below should be able to handle any network status, including dropped connections. It is written in an event-driven fashion as to not block your eggdrop, and makes use of a callback function.

You start the connection test by calling testConnect with the parameters host, port, and your callback function; ie:

Code: Select all

testConnect 127.0.0.1 80 mycallback
The callback function should take two arguments, status and message.
The meaning of status is as below:
  • Error:
    An error occurred while creating the socket. Most likely the hostname could not be resolved or is invalid. Message contains the error-message.
  • Rejected:
    The connection was rejected by the remote end. Message contains the error-message.
  • Connected:
    The connection was accepted by the remote end, and further closed by the script. Message contains the socket id that was used.
  • TimeoutSuccess:
    The connection timed out. The script successfully closed the socket. Message is typically empty.
  • TimeoutError:
    The connection timed out. The script encountered an error while trying to close the socket. Message contains the error-message.

Code: Select all

proc testConnect {host port callback} {
 if {![catch {socket -async $host $port} sock]} {
  fconfigure $sock -blocking off
  set after [after 10000 [list cleanupSocket $sock $callback]]
  fileevent $sock writable [list socketWritable $sock $callback $after]
 } else {
  $callback Error $sock
 }
}

proc socketWritable {socket callback after} {
 after cancel $after
 puts $socket ""
 if {![catch {flush $socket} status]} {
  close $socket
  $callback Connected "$socket"
 } {
  close $socket
  $callback Rejected "$socket: $status"
 }
}

proc cleanupSocket {socket callback} {
 if {[llength [file channels $socket]] > 0} {
  if {![catch {close $socket} status]} {
   $callback TimeoutSuccess "$socket: $status"
  } {
   $callback TimeoutError "$socket: $status"
  }
 }
}
NML_375
Post Reply