| View previous topic :: View next topic |
| Author |
Message |
honeybee Halfop
Joined: 01 Jan 2006 Posts: 80
|
Posted: Fri May 09, 2008 10:48 am Post subject: socket issues. |
|
|
I'm trying to access my website with
| Code: | 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: | | if {[catch {set sock [socket -async $myurl $myport] } err]} { |
just a thought.
I also thought of changing
| Code: | 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. |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Fri May 09, 2008 11:30 am Post subject: |
|
|
The cause for the lag is this part:
| Code: | 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, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
honeybee Halfop
Joined: 01 Jan 2006 Posts: 80
|
Posted: Fri May 09, 2008 2:43 pm Post subject: |
|
|
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 |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Fri May 09, 2008 2:56 pm Post subject: |
|
|
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, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
honeybee Halfop
Joined: 01 Jan 2006 Posts: 80
|
Posted: Fri May 09, 2008 2:59 pm Post subject: |
|
|
| thanks for your prompt reply can you please show me an example? |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Fri May 09, 2008 3:16 pm Post subject: |
|
|
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: | 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, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
strikelight Owner

Joined: 07 Oct 2002 Posts: 708
|
Posted: Fri May 09, 2008 6:22 pm Post subject: |
|
|
| 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. |
|
| Back to top |
|
 |
honeybee Halfop
Joined: 01 Jan 2006 Posts: 80
|
Posted: Sat May 10, 2008 9:41 am Post subject: |
|
|
| 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: | 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"
} |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Sat May 10, 2008 11:29 am Post subject: |
|
|
Yup. Except bgerror is expected to have one parameter (message);
| Code: | 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, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
honeybee Halfop
Joined: 01 Jan 2006 Posts: 80
|
Posted: Sat May 10, 2008 11:47 am Post subject: |
|
|
| 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. |
|
| Back to top |
|
 |
Ofloo Owner
Joined: 13 May 2003 Posts: 953 Location: Belguim
|
Posted: Wed May 14, 2008 6:41 am Post subject: |
|
|
| Code: | 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 |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Wed May 14, 2008 9:55 am Post subject: |
|
|
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, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
|