AutoHotkey Community

It is currently May 27th, 2012, 5:24 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 140 posts ]  Go to page Previous  1 ... 5, 6, 7, 8, 9, 10  Next
Author Message
 Post subject:
PostPosted: February 3rd, 2011, 4:04 pm 
Thanks for the pointers, I'm now getting to the login stage. I'm stuck at the logging part:
Code:
#Include AHKsock.ahk
#Persistent
#SingleInstance, Off


Gui,Destroy
Gui,Add,Edit, w800 h400 hwndLogHwnd
Gui,Show,,TEST

AHKsock_Connect("10.10.10.1", 23, "OnEvent")

Return
onEvent(event, socket, name, addr, port, ByRef data, ByRef datalength)
{
   
      If(event = "RECEIVED"){
            UpdateLog(data)
         
       if (data = "ÿýÿý ÿý#ÿý'"){
            sTest = ÿüÿü ÿü#ÿü'
            AHKsock_Send(socket, &sTest, StrLen(sTest))
      }
      
       if (data = "ÿûÿýÿýÿûÿý!"){
            sTest = ÿüÿüÿüÿü
            AHKsock_Send(socket, &sTest, StrLen(sTest))
      }
      
       if (SubStr(data, -5, 6) = "user:") {
           sTest = root`r`n
            AHKsock_Send(socket, &sTest, StrLen(sTest))
      }
                     
   }
}

updateLog(log) {
   global LogHwnd
   ControlSend,,{end},ahk_id %LogHwnd%
   Control,EditPaste,%log%,,ahk_id %LogHwnd%
   ControlSend,,{end},ahk_id %LogHwnd%
}

F3::
reload
return


GuiClose:
Exitapp
return


Why does if (SubStr(data, -5, 6) = "user:") fail ?
Yet I know this is correct, also why is updateLog(data) only needed once ?

I'm assuming updateLog(data) is constantly running, so a substr of data will never = user:

Where data contains user: does work, but isn't very helpful.

How do I get just the last line of the data received so I can compare it ?

Thanks


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 3rd, 2011, 5:51 pm 
Offline

Joined: October 15th, 2007, 3:10 pm
Posts: 790
Location: England
Can't you just use if ( InStr( data, "user:" ) ) instead to test the whole data string? This will possibly allow you see the "user:" regardless of where it is in the most recently received data, allowing you to debug a bit more easily.

The updateLog(data) is only called once, because the whole thing is triggered onEvent, meaning that the whole thing will happen each time something is received (this could be hundreds of times in a session). Every time a RECEIVED event is handled, your code can check for anything in that data received.

_________________
My code is written for AHK Basic unless otherwise specified. This means it may not work in AHK_L (especially Unicode), due to a few known compatibility issues.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 4th, 2011, 5:28 pm 
OceanMachine wrote:
Can't you just use if ( InStr( data, "user:" ) ) instead to test the whole data string? This will possibly allow you see the "user:" regardless of where it is in the most recently received data, allowing you to debug a bit more easily.

The updateLog(data) is only called once, because the whole thing is triggered onEvent, meaning that the whole thing will happen each time something is received (this could be hundreds of times in a session). Every time a RECEIVED event is handled, your code can check for anything in that data received.


Looking for user: in the stream isn't an issue, but once I'm logged in is there any way to check for specific words with in each line, but not in the past / historical lines ??

Thanks


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 8th, 2011, 4:23 pm 
can anyone help with my above question ?

Thanks :)


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 8th, 2011, 5:15 pm 
Offline

Joined: October 15th, 2007, 3:10 pm
Posts: 790
Location: England
the "data" var should only contain what was last received over the socket - it won't contain everything ever.

If that isn't good enough, you could try pulling out everything after the last carriage return/linefeed within that data variable using a RegEx or something like that, if that will suffice?

Something like this may help you to get started - this will hopefully find the last occurrence of "user:" in the data. This will not necessarily be on the last line... is that how you want it?:
Code:
data =
(
user: username1
hello
user: joe.bloggs
)

if ( RegExMatch( data, "m).*(user:.*)$", foundstr ) )
  MsgBox, %foundstr1%
Else
  MsgBox, Not found in %foundstr%

ExitApp

_________________
My code is written for AHK Basic unless otherwise specified. This means it may not work in AHK_L (especially Unicode), due to a few known compatibility issues.


Last edited by OceanMachine on February 8th, 2011, 5:52 pm, edited 2 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 8th, 2011, 5:23 pm 
Offline

Joined: January 8th, 2007, 1:14 pm
Posts: 83
@TheGood

I've been wondering about the AHKsock_Send and ForceSend functions, specifically how the ForceSend checks/uses the send buffer size to avoid performance hit while normal Send does not.

Code:
iMaxChunk := AHKsock_SockOpt(iSocket, "SO_SNDBUF")


Seems like good idea to have it as optional function argument? i.e. something like this...

Code:
AHKsock_Send(iSocket, ptrData = 0, iLength = 0, bUseBufferLimit = False)


Then handle it properly inside AHKsock_Send just like in ForceSend does? In fact, you could do this and remove it completely from ForceSend? I'm assuming that if i don't handle this when using normal Send function, then you get the mentioned performance hit?

Am i missing something? I haven't tested this myself but probably will at some point, just wanted to ask about this. :)

Cheers!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 9th, 2011, 11:56 pm 
Offline

Joined: July 30th, 2007, 11:32 pm
Posts: 581
aaron_ca wrote:
can anyone help with my above question ?

Thanks :)

As OceanMachine said, you can't just do
Code:
if (data = "ÿýÿý ÿý#ÿý'"){
            sTest =
            AHKsock_Send(socket, &sTest, StrLen(sTest))
      }

because the data received will not necessarily be delimited as such. Read the section Receiving and Sending Data for more information. This is why we need the StreamProcessor() function in Example 3.


Mystiq wrote:
I've been wondering about the AHKsock_Send and ForceSend functions, specifically how the ForceSend checks/uses the send buffer size to avoid performance hit while normal Send does not.

Very good question!

Firstly, I designed AHKsock_Send() to be a 'direct' no-frills wrapper of WinSock's send(). And then AHKsock_ForceSend() serves as another layer of abstraction by wrapping AHKsock_Send().

With that aside, adding that feature to AHKsock_Send() wouldn't be much help. The maximum number of successful send() calls that would go through would be two (since the call after the first one will fill the send buffer completely), after which you would receive WSAEWOULDBLOCK.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 10th, 2011, 5:15 pm 
Offline

Joined: January 8th, 2007, 1:14 pm
Posts: 83
TheGood wrote:
With that aside, adding that feature to AHKsock_Send() wouldn't be much help. The maximum number of successful send() calls that would go through would be two (since the call after the first one will fill the send buffer completely), after which you would receive WSAEWOULDBLOCK.


I'm kinda confused about this now, which is to be expected i guess. ;)

My understanding of this mentioned performance issue is that if single send call fills the SO_SNDBUF which will then cause some unwanted delay. If you can send data below SO_SNDBUF then you wouldn't get this delay? Also i don't understand how this would work in ForceSend but not when using Send.

I actually added and tested (limits properly) a bit of code to the Send function but not tested performance compared to not having it. It goes right before the DllCall and the commented debug code.
Code:
;Check if we should limit the length to the send buffer size
If (bUseBufferLimit) {
   If ((iMaxChunk := AHKsock_SockOpt(iSocket, "SO_SNDBUF")) = -1)
      Return -6
   Else iLength := iLength > iMaxChunk ? iMaxChunk - 1 : iLength
}


I want to mention that i'm not really a programmer and AHKsock is my first time dealing with network "stuff" but the amount of documentation you've included has help me a lot in learning how it all works. I think big THANK YOU is in order! :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 10th, 2011, 11:25 pm 
Offline

Joined: July 30th, 2007, 11:32 pm
Posts: 581
Mystiq wrote:
My understanding of this mentioned performance issue is that if single send call fills the SO_SNDBUF which will then cause some unwanted delay. If you can send data below SO_SNDBUF then you wouldn't get this delay?

Yup, exactly! It's a little complicated, but basically if you fill up the buffer in one shot, the next send() will return WSAEWOULDBLOCK. But at the same time, the recipient is not sending an ACK right away (which would free up the buffer) and instead waits about 200 ms. This is in case even more data comes (in which case it can ACK all of it at once) or if the receiving app wants to send a reply (like an echo), in which case it can ACK and send data in one shot.

If you want more info on the subject:
http://en.wikipedia.org/wiki/TCP_delayed_acknowledgment
http://en.wikipedia.org/wiki/Nagle%27s_algorithm
http://www.stuartcheshire.org/papers/NagleDelayedAck/

So for 200 ms, communication is at a standstill, until the recipient finally decides that it might as well send an ACK, and then communication resumes until the next impasse.

Quote:
Also i don't understand how this would work in ForceSend but not when using Send.

I didn't say it wouldn't work. It would just not be worth it. ;)
The advantage that AHKsock_ForceSend has is that it can wait for the next SEND event, which AHKsock_Send cannot do that if it's to be used inside the event-handling function.

Quote:
I actually added and tested (limits properly) a bit of code to the Send function but not tested performance compared to not having it.

Should be interesting to see if there is a difference!

Quote:
I think big THANK YOU is in order! :)

Hehe, you're welcome! :)
AHKsock is by far the library I'm most proud of, because I've learned so much from it!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 11th, 2011, 4:13 pm 
TheGood wrote:
aaron_ca wrote:
can anyone help with my above question ?

Thanks :)

As OceanMachine said, you can't just do
Code:
if (data = "ÿýÿý ÿý#ÿý'"){
            sTest =
            AHKsock_Send(socket, &sTest, StrLen(sTest))
      }

because the data received will not necessarily be delimited as such. Read the section Receiving and Sending Data for more information. This is why we need the StreamProcessor() function in Example 3.


@TheGood
Thanks both of the replies make sense.. But I'm not sure how to use the stream processor in the way I would like my script to work.

Would it be possible for a 'very simple' example based on what I'm trying to do ?

Many Thanks


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 16th, 2011, 4:18 pm 
Hi
sorry to keep asking. I will get there ! :?

Can someone push me in the right direction with a 'simple' example of monitoring a stream and looking for matches.

eg:
Code:
if data = Users
send Username

How would I do that ?

thanks


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 17th, 2011, 1:41 am 
Offline

Joined: October 15th, 2007, 3:10 pm
Posts: 790
Location: England
You should find that just checking for your exact string in the data variable on each RECEIVED event will work fine in most cases.

If you really think that there will be so much data that the buffer will fill up and the output from your server will have to be split across multiple events, then you will have to perhaps combine the data from a couple of RECEIVED events and look again for the string you want to wait for. This is unlikely to happen if you are monitoring and responding to things at an interactive telnet session, especially with things like a login prompt). Usually a Login prompt string will be sent, and then it will wait for a response. Usually this will fit into one buffer, so your simple search will work in this case. It really depends on your environment and how simple you want the script to be.

The simple way would be to use if ( InStr( data, "user:" ) ) as I suggested before (but may fail under certain unlikely circumstances).

The more complicated but more robust way would be as per above... (would be more complicated but may work better under certain circumstances)...but you wanted a simple answer.

Give the below examples a try and have a look to see whether either of them is suitable for you. If so, then plug either of them in to AHKSock to find the data on a RECEIVING event.
Code:
data =
(
user: username1
hello
user: joe.bloggs
some text here
user: user2
some unexpected text here
) ; this data is just an example of what you might receive over the socket.

; Note: the first example below will not match because the string "user:"
; is not in the LAST line (which is what you asked for).  If you want to
; match the last occurrence of the string "user:" anywhere in the received
; data (from just the most recent event) then use the second example.


;Example 1: match in the LAST LINE only
RegExMatch( data, "`a).*$", lastline ) ; get the last line in the data received

if ( InStr( lastline, "user:" ) )
  MsgBox, Example 1`nFound string in last line: "%lastline%"`n`nFull data is: `n"%data%"
Else
  MsgBox, Example 1`nString not found in last line: "%lastline%"`n`nFull data is: `n"%data%"
 

;Example 2: find the last match found on any single line anywhere in the last received data chunk (if at all)
Line := "", Num := 0
Loop, parse, data, `n, `r
{
   ; this will keep looping until the last line of the data, so will always find the last matching line (if any)
   If ( InStr( A_LoopField, "user:" ) )
   {
      Line := A_LoopField
      Num := A_Index
   }
}

If ( Line )
   MsgBox, Example 2`nFound string in line %Num%: "%Line%"`n`nFull data is: `n"%data%"
Else
  MsgBox, Example 2`nString not found in data.`n`nFull data is: `n"%data%"

_________________
My code is written for AHK Basic unless otherwise specified. This means it may not work in AHK_L (especially Unicode), due to a few known compatibility issues.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 1st, 2011, 3:37 pm 
aaron_ca wrote:
Code:
#Include AHKsock.ahk
#Persistent
#SingleInstance, Off


Gui,Destroy
Gui,Add,Edit, w800 h400 hwndLogHwnd
Gui,Show,,TEST

AHKsock_Connect("10.10.10.1", 23, "OnEvent")

Return
onEvent(event, socket, name, addr, port, ByRef data, ByRef datalength)
{
   
      If(event = "RECEIVED"){
            UpdateLog(data)
         
       if (data = "ÿýÿý ÿý#ÿý'"){
            sTest = ÿüÿü ÿü#ÿü'
            AHKsock_Send(socket, &sTest, StrLen(sTest))
      }
      
       if (data = "ÿûÿýÿýÿûÿý!"){
            sTest = ÿüÿüÿüÿü
            AHKsock_Send(socket, &sTest, StrLen(sTest))
      }
      
       if (SubStr(data, -5, 6) = "user:") {
           sTest = root`r`n
            AHKsock_Send(socket, &sTest, StrLen(sTest))
      }
                     
   }
}

updateLog(log) {
   global LogHwnd
   ControlSend,,{end},ahk_id %LogHwnd%
   Control,EditPaste,%log%,,ahk_id %LogHwnd%
   ControlSend,,{end},ahk_id %LogHwnd%
}

F3::
reload
return


GuiClose:
Exitapp
return


Hi
1st time post, please be nice :)

Is there anyway to do something similar to the above, but it the connect stops/fails/disconnects then keep trying until it re connects ?

thanks


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: March 24th, 2011, 3:39 am 
great!


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: April 24th, 2011, 12:38 am 
Offline

Joined: April 8th, 2009, 7:49 pm
Posts: 6073
Location: San Diego, California
Example 3 - Chatting wrote:
txtInput:

/*! This GUI event will be called everytime the text in the Edit control changes. The idea is to send a notification to
the peer when the user starts/stops typing. We do this using the typing update frame. See the StreamProcessor function
for more information on frames.
*/


It only sees to report when the peer starts typing. :(

Is there also a way to report when the user stops or pauses typing?


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 140 posts ]  Go to page Previous  1 ... 5, 6, 7, 8, 9, 10  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Google Feedfetcher, sks and 12 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group