mIRC Home    About    Download    Register    News    Help

Print Thread
Page 1 of 2 1 2
#191834 16/12/07 04:34 PM
Joined: Jan 2004
Posts: 162
R
RRX Offline OP
Vogon poet
OP Offline
Vogon poet
R
Joined: Jan 2004
Posts: 162
The help file says:
"$sockerr is set to a value after each socket command/event and must be checked after each socket command and before processing an event to see if an error occurred."

Does that mean that everytime I /sockread in an on sockread command I have to check $sockerr?


Last edited by RRX; 16/12/07 04:34 PM.
Joined: May 2007
Posts: 89
T
Babel fish
Offline
Babel fish
T
Joined: May 2007
Posts: 89
Yes, because when interacting with a remote server/application, the client must check each received packet to see if an error occured.

Something like this will suffice.

Code:
If $sockerr { Echo -at - Error on $sockname - | Return }


Cordialement


tropnul
Joined: Jan 2004
Posts: 162
R
RRX Offline OP
Vogon poet
OP Offline
Vogon poet
R
Joined: Jan 2004
Posts: 162
That would also mean that if a header is sent in on sockopen event, I have to check after every /sockwrite if $sockerr is > 0, I saw nobody doing that so far?

Joined: Dec 2002
Posts: 2,962
S
Hoopy frood
Offline
Hoopy frood
S
Joined: Dec 2002
Posts: 2,962
They should do, but many people don't bother with pesky things like error checking. Then one day when things break without any kind of error message they end up on a forum like this wondering what happened.


Spelling mistakes, grammatical errors, and stupid comments are intentional.
Joined: Jan 2007
Posts: 1,156
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Jan 2007
Posts: 1,156
lol


if ($sockerr > 0) { return }

Joined: Oct 2007
Posts: 51
T
Babel fish
Offline
Babel fish
T
Joined: Oct 2007
Posts: 51
on *:sockwrite:*:{ if ($sockerr) { echo -at Write error: $sockname | halt } }

Joined: May 2007
Posts: 89
T
Babel fish
Offline
Babel fish
T
Joined: May 2007
Posts: 89
Originally Posted By: ""
That would also mean that if a header is sent in on sockopen event, I have to check after every /sockwrite if $sockerr is > 0, I saw nobody doing that so far?


No, the error check should be done only once, generally at the top of the event.

Let's take an example (which is the way things should be done)
Code:
On *:SockOpen:Name:{
  If $sockerr { Echo -st - Error on $sockname - | Return }
  Var %s = SockWrite -n $sockname
  %s NICK SomeNickname
  %s USER something something something :Just Testing
}


Of course, something like the following is useless.
Code:
On *:SockOpen:Name:{
  If $sockerr { Echo -st - Error on $sockname - | Return }
  Var %s = SockWrite -n $sockname
  %s NICK SomeNickname
  If $sockerr { Echo -st - Error on $sockname - | Return }
  %s USER something something something :Just Testing
  If $sockerr { Echo -st - Error on $sockname - | Return }
}

Because, in the case of an error, the socket is automatically closed by mIRC, so a unique check will do it. smile

NB: Note the use of "Var %s = SockWrite -n $sockname", which is not a compulsory method. I like to do that when I'll have to do a series of /sockwrite. It then neatens the source. It's only a matter of taste and aesthetics. smile


tropnul
Joined: Jan 2004
Posts: 162
R
RRX Offline OP
Vogon poet
OP Offline
Vogon poet
R
Joined: Jan 2004
Posts: 162
Originally Posted By: TropNul
Originally Posted By: ""
That would also mean that if a header is sent in on sockopen event, I have to check after every /sockwrite if $sockerr is > 0, I saw nobody doing that so far?


No, the error check should be done only once, generally at the top of the event.

Let's take an example (which is the way things should be done)
Code:
On *:SockOpen:Name:{
  If $sockerr { Echo -st - Error on $sockname - | Return }
  Var %s = SockWrite -n $sockname
  %s NICK SomeNickname
  %s USER something something something :Just Testing
}


Of course, something like the following is useless.
Code:
On *:SockOpen:Name:{
  If $sockerr { Echo -st - Error on $sockname - | Return }
  Var %s = SockWrite -n $sockname
  %s NICK SomeNickname
  If $sockerr { Echo -st - Error on $sockname - | Return }
  %s USER something something something :Just Testing
  If $sockerr { Echo -st - Error on $sockname - | Return }
}

Because, in the case of an error, the socket is automatically closed by mIRC, so a unique check will do it. smile

NB: Note the use of "Var %s = SockWrite -n $sockname", which is not a compulsory method. I like to do that when I'll have to do a series of /sockwrite. It then neatens the source. It's only a matter of taste and aesthetics. smile

Thats rather contradiction, as said, according to the help, any of the /sockwrite's can cause $sockerr to be > 0, so if only a check after the on sockopen event, it would be possible that for example the first /sockwrite fails with an error, so the socket is then closed by mirc but the code from the event keeps running until the end, return or halt, so this would halt it with an error in status, and it's also possible a script has to perform certain code in case of failure so it has to check $sockerr everytime because mirc stops executing after an error and the script wouldnt be able to perform that code anymore (or it would need an :error label)
So an unique check will not do it then.

Another text from the help:
"On error: if a /sockwrite fails, it sets $sock().wserr to the error value, and triggers the on sockwrite event with $sockerr set."
The help really sucks when it comes to details.
It doesn't say it triggers the on sockwrite AFTER the current code has finished executing, so it would mean then that mIRC triggers the on sockwrite event with $sockerr check - immediately, similar to /signal -n (so far the only such case I know is when doing /disconnect, the on disconnect event is triggered, and then mirc proceeds executing the code after /disconnect)
It's all...guessing.


Joined: May 2007
Posts: 89
T
Babel fish
Offline
Babel fish
T
Joined: May 2007
Posts: 89
I'll try to clarify the issue. (I'm no socket expert though)

When the different events "On sockopen", "On sockwrite" and "On sockread" are triggered, any error that may have been received or sent can/must be detected at the top of the event directly without having to check for an error after each socket command. When you do /sockopen, "on sockopen" is triggered. When you do /sockwrite, "on sockwrite" is triggered (when all the data has been sent) and eventually, because of the /sockwrite, the remote application/server will produce a reply and that's when "on sockread" is triggered. Also, "on sockread" is triggered whenever you receive something remotely, whether you did a /sockwrite or not.

I mean by this that the "On sockopen" event should be coupled with a "On sockread" and/or with a "On sockwrite" event to be able to get the error (if any) when the remote server/application replies.

The "on sockopen" and "on sockwrite" only triggers when the client 'opens' and 'writes to' a socket and will produce only client errors. To be able to see the remote server's/application's errors (if any), you must use "on sockread" with the same "if $sockerr { return }" check on top.

Basically it should ressemble the following:
Code:
on *:sockopen:name:{
  if $sockerr { echo -st - $sockname error - $sock($sockname).wserr | return }
  commands
}
On *:sockread:name:{
  if $sockerr { echo -st - $sockname error - $sock($sockname).wserr | return }
  commands
}
on *:sockwrite:name:{
  if $sockerr { echo -st - $sockname error - $sock($sockname).wserr | return }
  commands
}

I don't know if I've been clear but I've tried to. :s

--
I'll add this to the explanation:

Even if an error occured for example as a consequence of the 7th /sockwrite in a 'on sockopen' event, the error would only be detected in the 'on sockwrite' event when all the contents of that /sockwrite have been sent!

Same when receiving data. Errors will be detected only when your mIRC actually receives the data, that is, when the 'on sockread' event is triggered.
--

Cordialement

Last edited by TropNul; 17/12/07 05:31 AM.

tropnul
Joined: Jan 2004
Posts: 162
R
RRX Offline OP
Vogon poet
OP Offline
Vogon poet
R
Joined: Jan 2004
Posts: 162
This is the reason for my subject:
Code:
on *:sockread:VIPCheck*: {
  if ($sockerr == 3) { echo -tac Highlight * error on connected socket occurred for $sockname ( $sock($sockname).wserr ) | halt }
  if ($sockerr) { echo -tac Highlight * Unknown sock error for $sockname | halt }
  var %data
  while (1) {
    sockread %data
    if (!$sockbr) break
    if ($sockerr == 3) { echo -tac Highlight * error on connected socket occurred for $sockname ( $sock($sockname).wserr ) | halt }
    if ($sockerr) { echo -tac Highlight * Unknown sock error for $sockname | halt }
    if (($regex(%data,/<user(?: (opped|voiced)="true"|())>([^<]+)<\/user>/)) && ($istok($gettok($sock($sockname).mark,2-,32),$regml(2),32))) {
      if (($regml(1) == opped) && ($me isop $gettok($sock($sockname).mark,1,32)) && ($regml(2) ison $v2) && ($v1 !isop $v2)) .mode $v2 +o $v1
    }
  }
}

I was surprised to see $sockerr checks in the loop that reads from the socket.
Is this needed or not?

Joined: May 2007
Posts: 89
T
Babel fish
Offline
Babel fish
T
Joined: May 2007
Posts: 89
Well, if the coder wants to have a different error message when $sockerr equals to 3, then the method is quite good (though, imho, too much ifs are used here).

Have in mind that, for each on sockread trigger, $sockerr is allocated only one value(0 = no error, 1-n = error), so checking it at different stages won't change its value.

In the example you posted, the coder just wanted to have the error message for $sockerr = 3 displayed. Now, the while loop is not necessary when sockreading sockets. I would do something like this instead.

Code:
on *:sockread:VIPCheck*: {
  if $sockerr {
    echo -tac Highlight * $iif(($v1 == 3),error on connected socket occurred for $sockname $sock($sockname).wserr,Unknown sock error for $sockname)
    return
  }
  var %data
  sockread %data
  if (!$sockbr) return
  elseif (($regex(%data,/<user(?: (opped|voiced)="true"|())>([^<]+)<\/user>/)) && ($istok($gettok($sock($sockname).mark,2-,32),$regml(2),32))) {
    if (($regml(1) == opped) && ($me isop $gettok($sock($sockname).mark,1,32)) && ($regml(2) ison $v2) && ($v1 !isop $v2)) .mode $v2 +o $v1
  }
}


Hope this helped.

Cordialement


tropnul
Joined: Jan 2004
Posts: 162
R
RRX Offline OP
Vogon poet
OP Offline
Vogon poet
R
Joined: Jan 2004
Posts: 162
Originally Posted By: TropNul

Have in mind that, for each on sockread trigger, $sockerr is allocated only one value(0 = no error, 1-n = error), so checking it at different stages won't change its value.

Then the $sockerr checks inside the loop are useless, thats what I wanted to know.

Regarding the looping, the help says its better to loop instead of letting mirc retriggering the event, the first is much faster.

Joined: Jan 2007
Posts: 1,156
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Jan 2007
Posts: 1,156
I dont know if this will help, but this is what I have learned.

on *:Sockread:sockname:{
if ($sockerr > 0) { return }


sockread lines



:error
if ($error) { echo -s $error | reseterror }
}

Notice I use return instead oh halt. This is so mIRC doesn't halt all currently running scripts. Only the one that has the error.

Joined: Jan 2004
Posts: 162
R
RRX Offline OP
Vogon poet
OP Offline
Vogon poet
R
Joined: Jan 2004
Posts: 162
Originally Posted By: DJ_Sol
I dont know if this will help, but this is what I have learned.

on *:Sockread:sockname:{
if ($sockerr > 0) { return }


sockread lines



:error
if ($error) { echo -s $error | reseterror }
}

Notice I use return instead oh halt. This is so mIRC doesn't halt all currently running scripts. Only the one that has the error.

So far I use only a $sockerr check in the beginning of a socket event, unlike what is done in the script piece I pasted, it also checks after every /sockread and my question was if a /sockread can make $sockerr have a new value, for example, the on sockread triggers, no error ($sockerr 0), but after the first (or 12th, doesnt matter), if its possible that it suddenly does get a value (and important remind: all in the execution time of this same on sockread event).

That :error label is not related to my question, I was talking ab out the $sockerr identifier.

Btw, (offtopic), /halt only halts the execution from the event that is executed, halt will not stop mirc from executioning another event with the same triggering conditions (in another file ofcourse, because implementation causes it to only execute the first instance if both are in same scriptfile.
So there is nothing wrong with using /halt instead of /return, in an event.
The place where this choice does make a difference is an alias, if /halt is used there, it will stop the execution of the whole currently processed code, so also the calling place, no matter how many levels.

Joined: Jan 2004
Posts: 162
R
RRX Offline OP
Vogon poet
OP Offline
Vogon poet
R
Joined: Jan 2004
Posts: 162
Originally Posted By: starbucks_mafia
They should do, but many people don't bother with pesky things like error checking. Then one day when things break without any kind of error message they end up on a forum like this wondering what happened.

/sockread reads from a socket buffer, right?
I assume this buffer is located in memory from the mIRC process, right?
Now, suppose mIRC is busy processing an on sockread event, can I assume 'mIRC busy' means that it doesn't receive new data inside the mIRC socket buffer, because the operating system cannot pass it to mIRC since it's not ready (busy processing on sockread event)?

If above is true, then $sockerr cannot change since mIRC started processing the on sockread event. Also, the amount bytes in the mIRC socketbuffer can only drop equal bytes as /sockread reads.
Maybe put in another way: suppose on sockread event triggers, the total bytes in the buffer is 1000, if you make the sum of all $sockbr's after /sockreads, it can only be 1000 if you read until $sockbr == 0 and never higher?

Joined: Jun 2004
Posts: 139
N
Vogon poet
Offline
Vogon poet
N
Joined: Jun 2004
Posts: 139
Hi there,
A question here which is kinda related to this topic.

When a sockread event is triggered I work out the size of the file and compare it using $sock(sockname).rcvd to know when I have got everything in the file, at which time I break out of the sockread loop. Or at least thats the idea.

So far it only works when I allow mIRC to re-trigger the sockread event, rather then trigger once and loop till finished because it would 'appear' that $sock(sockname).rcvd only updates after the code finishes, and of course when looping that will be never if $sock(sockname).rcvd never updates.

Any info on this would be great!

Thanks


Ninko

Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
you should know how many bytes you received every loop iteration, just keep a local count.

Code:
var %x = $sock($sockname).rcvd
while ($true) {
  sockread &bvar
  inc %x $sockbr
  if ($sockbr == 0 || %x >= %THEFILESIZE) break
}


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Jun 2004
Posts: 139
N
Vogon poet
Offline
Vogon poet
N
Joined: Jun 2004
Posts: 139
So, this wouldn't work is what your saying, you must use $sockbr in loops?

Code:
:start
sockread &bvar
%x = $sock(sockname).rcvd
if (%x == %THEFILESIZE) {
  code etc
}
else {
  goto start
}



Ninko

Joined: Jun 2004
Posts: 139
N
Vogon poet
Offline
Vogon poet
N
Joined: Jun 2004
Posts: 139
I just did a little test.

Code:
  %1 = 0
  :test
  sockread &temp
  bwrite etc etc &temp
  %x = $sock(sockname).rcvd
  echo -a %x %THEFILESTZE $sockbr
  %1 = %1 + 1
  if (%1 == 10) { halt }
  else { goto test }


The results were:

289 17935 0
289 17935 0
289 17935 0
289 17935 0
289 17935 0
289 17935 0
289 17935 0
289 17935 0
289 17935 0
289 17935 0
4385 17935 4096
4385 17935 0
4385 17935 0
4385 17935 0
4385 17935 0
4385 17935 0
4385 17935 0
4385 17935 0
4385 17935 0
4385 17935 0
8481 17935 4096
8481 17935 0
8481 17935 0
8481 17935 0
8481 17935 0
8481 17935 0
8481 17935 0
8481 17935 0
8481 17935 0
8481 17935 0
12577 17935 4096
12577 17935 0
12577 17935 0
12577 17935 0
12577 17935 0
12577 17935 0
12577 17935 0
12577 17935 0
12577 17935 0
12577 17935 0
16673 17935 4096
16673 17935 0
16673 17935 0
16673 17935 0
16673 17935 0
16673 17935 0
16673 17935 0
16673 17935 0
16673 17935 0
16673 17935 0
17935 17935 1262
17935 17935 0
17935 17935 0
17935 17935 0
17935 17935 0
17935 17935 0
17935 17935 0
17935 17935 0
17935 17935 0
17935 17935 0

So once again, $sock(sockname).rcvd doesn't update untill re-triggered along with $sockbr.

Am I missing something here?


Ninko

Joined: Jun 2004
Posts: 139
N
Vogon poet
Offline
Vogon poet
N
Joined: Jun 2004
Posts: 139
Must just be me then...


Ninko

Page 1 of 2 1 2

Link Copied to Clipboard