egghelp.org community Forum Index
[ egghelp.org home | forum home ]
egghelp.org community
Discussion of eggdrop bots, shell accounts and tcl scripts.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

socket issues.

 
Post new topic   Reply to topic    egghelp.org community Forum Index -> Scripting Help
View previous topic :: View next topic  
Author Message
honeybee
Halfop


Joined: 01 Jan 2006
Posts: 80

PostPosted: Fri May 09, 2008 10:48 am    Post subject: socket issues. Reply with quote

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
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Fri May 09, 2008 11:30 am    Post subject: Reply with quote

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
View user's profile Send private message
honeybee
Halfop


Joined: 01 Jan 2006
Posts: 80

PostPosted: Fri May 09, 2008 2:43 pm    Post subject: Reply with quote

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
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Fri May 09, 2008 2:56 pm    Post subject: Reply with quote

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
View user's profile Send private message
honeybee
Halfop


Joined: 01 Jan 2006
Posts: 80

PostPosted: Fri May 09, 2008 2:59 pm    Post subject: Reply with quote

thanks for your prompt reply can you please show me an example?
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Fri May 09, 2008 3:16 pm    Post subject: Reply with quote

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
View user's profile Send private message
strikelight
Owner


Joined: 07 Oct 2002
Posts: 708

PostPosted: Fri May 09, 2008 6:22 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
honeybee
Halfop


Joined: 01 Jan 2006
Posts: 80

PostPosted: Sat May 10, 2008 9:41 am    Post subject: Reply with quote

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
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Sat May 10, 2008 11:29 am    Post subject: Reply with quote

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
View user's profile Send private message
honeybee
Halfop


Joined: 01 Jan 2006
Posts: 80

PostPosted: Sat May 10, 2008 11:47 am    Post subject: Reply with quote

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
View user's profile Send private message
Ofloo
Owner


Joined: 13 May 2003
Posts: 953
Location: Belguim

PostPosted: Wed May 14, 2008 6:41 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Wed May 14, 2008 9:55 am    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    egghelp.org community Forum Index -> Scripting Help All times are GMT - 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Forum hosting provided by Reverse.net

Powered by phpBB © 2001, 2005 phpBB Group
subGreen style by ktauber