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.

socket issues.

Help for those learning Tcl or writing their own scripts.
Post Reply
h
honeybee
Halfop
Posts: 80
Joined: Sun Jan 01, 2006 12:42 pm

socket issues.

Post by honeybee »

I'm trying to access my website with

Code: Select all

if {[catch {set sock [socket $myurl $myport] } err]} {
    putlog "error: $err"
  return 0
} else {
  puts $sock "GET /administrator.cgi?pass=$adminpass&mode=viewxml HTTP/1.0"
  puts $sock "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.9)"
  puts $sock "Host: $myurl"
  puts $sock "Connection: close"
  puts $sock ""
  flush $sock
  while {[eof $sock] != 1} {
# do this...
  }
}  
this works fine but issue is by eggdrop lags alot.
should i change it to.

Code: Select all

if {[catch {set sock [socket -async $myurl $myport] } err]} {
just a thought.
I also thought of changing

Code: Select all

  puts $sock ""
  flush $sock
to:
if [info exists sock] {close $sock}
Another question is is it safe to use sock because i read some where in users post sock connetion can be used to access your bot and shell if someone know the url & port.

Thank you.
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

The cause for the lag is this part:

Code: Select all

  while {[eof $sock] != 1} {
# do this...
  }
This will prevent your eggdrop from performing any further actions until the whole webpage has been recieved, or connection has been dropped. Changing to async connections will not make much difference.

I would recommend that you have a look at the http-package instead, as this package supports callback functions.

Sockets opened with "socket" has no way of interacting with your tcl parser or eggdrop environment, other than the means you provide using gets, puts, read, etc. Unless you actually read the received text using puts or read, it'll just sit in an input buffer until the socket is closed.
Also, knowing the url & port of the remote site has no impact on the security of your eggdrop - just as it won't on your web-browser...
NML_375
h
honeybee
Halfop
Posts: 80
Joined: Sun Jan 01, 2006 12:42 pm

Post by honeybee »

yes but I will have to re-do whole script again which is kinda too much at the moment. I will surely look into it when have time.
do you have suggestion to fix this issue temp
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Nothing that would'nt cause the same amount of rewriting..

Basically, what you need, is to remove all socket communications out of that proc, and use tcl's event-engine to make your request and read the result. As long as your proc keeps running, it will prevent your eggdrop from doing anything else, possibly causing it to timeout and disconnect.
NML_375
h
honeybee
Halfop
Posts: 80
Joined: Sun Jan 01, 2006 12:42 pm

Post by honeybee »

thanks for your prompt reply can you please show me an example?
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Try searching the forum for threads related to "fileevent", as this is the mechanism you'll end up using for events.

A very rough example however:

Code: Select all

proc isReadable {socket} {
 if {[gets $socket line] < 0} {
  if {[eof $socket]} {
   close $socket
   #Cleanup code: Connection closed by remote host
   isFinal $socket
   return
  }
 } else {
  lappend ::readBuffer($socket) $line
 }
}

proc isFinal {socket} {
 #do something intelligent with the data we received, and then cleanup...
 foreach line $::readBuffer($socket) {
  putlog "$line"
 }
 unset ::readBuffer
}

...

set fId [socket $hostIP $hostPort]
fconfigure $fId -blocking 0
set ::readBuffer($fId) [list]
fileevent $fId readable [list isReadable $fId]
This will open a connection to $hostIp:$hostPort, and read all data one line at a time, appending them to the global list readBuffer, until the remote end closes the connection. Then isFinal will be called to do something creative with the received data.
NML_375
User avatar
strikelight
Owner
Posts: 708
Joined: Mon Oct 07, 2002 10:39 am
Contact:

Post by strikelight »

It would most definitley be easier for you (given the original code you posted) to simply use the http package (with the -command switch) or the egghttp.tcl script. There is an egghttp.tcl example at http://www.tclscript.com/egghttp_tut.shtml which wouldn't be hard to apply to the http package as well.
h
honeybee
Halfop
Posts: 80
Joined: Sun Jan 01, 2006 12:42 pm

Post by honeybee »

nml375 wrote:Try searching the forum for threads related to "fileevent", as this is the mechanism you'll end up using for events.

A very rough example however:

Code: Select all

proc isReadable {socket} {
 if {[gets $socket line] < 0} {
  if {[eof $socket]} {
   close $socket
   #Cleanup code: Connection closed by remote host
   isFinal $socket
   return
  }
 } else {
  lappend ::readBuffer($socket) $line
 }
}

proc isFinal {socket} {
 #do something intelligent with the data we received, and then cleanup...
 foreach line $::readBuffer($socket) {
  putlog "$line"
 }
 unset ::readBuffer
}

...

set fId [socket $hostIP $hostPort]
fconfigure $fId -blocking 0
set ::readBuffer($fId) [list]
fileevent $fId readable [list isReadable $fId]
This will open a connection to $hostIp:$hostPort, and read all data one line at a time, appending them to the global list readBuffer, until the remote end closes the connection. Then isFinal will be called to do something creative with the received data.
thanks, I'm tryin to redo it with your suggestion.
But for event based code I need to have bgerror to catch the exact errors right?
proc bgerror {} {
putlog "bgerror: errorInfo: $::errorInfo"
putlog "bgerror: errorCode: $::errorCode"
}
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Yup. Except bgerror is expected to have one parameter (message);

Code: Select all

proc bgerror {msg} {
 putlog "bgerror: $msg"
 putlog "  ($::errorCode) $::errorInfo"
}
I would still recommend using the http-package, as it pretty much does the same - unless you wish to practice using tcl-events.
NML_375
h
honeybee
Halfop
Posts: 80
Joined: Sun Jan 01, 2006 12:42 pm

Post by honeybee »

nml375 wrote: I would still recommend using the http-package, as it pretty much does the same - unless you wish to practice using tcl-events.
well i guess http would be the better choice but I sitll want to try tcl-event its logical and clearing many things.
O
Ofloo
Owner
Posts: 953
Joined: Tue May 13, 2003 1:37 am
Location: Belguim
Contact:

Post by Ofloo »

Code: Select all

if {[info exists _forever_]} else {unset _forever_}
if {[catch {socket localhost 25} sock]} {
  puts "Error couldn't connect"
  set _forever_ {}
} else {
  fileevent $sock writable [list socket_async_callback $sock] 
}

proc socket_async_callback {sock} {
  global _forever_
  if {[string equal {} [fconfigure $sock -error]]} {
    while {![eof $sock]} {
      puts $sock "blah blah"
      flush $sock
      gets $sock buf
      puts "$buf"
    }
  } else {
    puts [fconfigure $sock -error]
  }
  close $sock
  set _forever_ {}
}

vwait _forever_
This should work in a shell script, i do not agree with fconfigure because it will drive the cpu crazy, i used to do it as well and a socket script ended up using 100% cpu, that's why i use/prefer flush instead, ..

You should ignore/comment the lines with _forever_ once you use this in an eggdrop script.
XplaiN but think of me as stupid
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Hmm... never had that issue with nonblocking channels and "readable" fileevents. Can't tell 'bout "writable", as I hardly ever use 'em...

Properly configured, the readable-event would only be dispatched once for each tcp-packet recieved until a whole line can be recieved. Also, the way eggdrop invokes Tcl_DoOneEvent() should make it very hard to steal 100% cpu unless you use some loop within your event-handler.
NML_375
Post Reply