|
Joined: Jan 2004
Posts: 162
Vogon poet
|
OP
Vogon poet
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
Babel fish
|
Babel fish
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. If $sockerr { Echo -at - Error on $sockname - | Return } Cordialement
tropnul
|
|
|
|
Joined: Jan 2004
Posts: 162
Vogon poet
|
OP
Vogon poet
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
Hoopy frood
|
Hoopy frood
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
Hoopy frood
|
Hoopy frood
Joined: Jan 2007
Posts: 1,156 |
lol
if ($sockerr > 0) { return }
|
|
|
|
Joined: Oct 2007
Posts: 51
Babel fish
|
Babel fish
Joined: Oct 2007
Posts: 51 |
on *:sockwrite:*:{ if ($sockerr) { echo -at Write error: $sockname | halt } }
|
|
|
|
Joined: May 2007
Posts: 89
Babel fish
|
Babel fish
Joined: May 2007
Posts: 89 |
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)
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.
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. 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.
tropnul
|
|
|
|
Joined: Jan 2004
Posts: 162
Vogon poet
|
OP
Vogon poet
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? 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)
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.
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. 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. 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
Babel fish
|
Babel fish
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:
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
Vogon poet
|
OP
Vogon poet
Joined: Jan 2004
Posts: 162 |
This is the reason for my subject:
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
Babel fish
|
Babel fish
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. 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
Vogon poet
|
OP
Vogon poet
Joined: Jan 2004
Posts: 162 |
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
Hoopy frood
|
Hoopy frood
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
Vogon poet
|
OP
Vogon poet
Joined: Jan 2004
Posts: 162 |
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
Vogon poet
|
OP
Vogon poet
Joined: Jan 2004
Posts: 162 |
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
Vogon poet
|
Vogon poet
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
Hoopy frood
|
Hoopy frood
Joined: Oct 2003
Posts: 3,918 |
you should know how many bytes you received every loop iteration, just keep a local count.
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
Vogon poet
|
Vogon poet
Joined: Jun 2004
Posts: 139 |
So, this wouldn't work is what your saying, you must use $sockbr in loops? :start
sockread &bvar
%x = $sock(sockname).rcvd
if (%x == %THEFILESIZE) {
code etc
}
else {
goto start
}
Ninko
|
|
|
|
Joined: Jun 2004
Posts: 139
Vogon poet
|
Vogon poet
Joined: Jun 2004
Posts: 139 |
I just did a little test.
%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
Vogon poet
|
Vogon poet
Joined: Jun 2004
Posts: 139 |
Must just be me then...
Ninko
|
|
|
|
|