From WikiChip
Editing mirc/commands/sockread
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.
The edit can be undone.
Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
This page supports semantic in-text annotations (e.g. "[[Is specified as::World Heritage Site]]") to build structured and queryable content provided by Semantic MediaWiki. For a comprehensive description on how to use annotations or the #ask parser function, please have a look at the getting started, in-text annotation, or inline queries help pages.
Latest revision | Your text | ||
Line 1: | Line 1: | ||
− | {{ | + | {{mIRC menu}} |
The '''/sockread''' command reads bytes from the receive buffer of a socket connection into a specified variable. This command must be and is to be used inside socket events. | The '''/sockread''' command reads bytes from the receive buffer of a socket connection into a specified variable. This command must be and is to be used inside socket events. | ||
mIRC in general only understand {{mIRC|$crlf}} terminated line. With socket, mIRC only understands {{mIRC|$lf}} terminated line (any {{mirc|$cr}} before a {{mirc|$lf}} is removed). | mIRC in general only understand {{mIRC|$crlf}} terminated line. With socket, mIRC only understands {{mIRC|$lf}} terminated line (any {{mirc|$cr}} before a {{mirc|$lf}} is removed). | ||
− | The number of bytes waiting to be read can be retrieved using {{mIRC|$sock|$sock(name).rq | + | The number of bytes waiting to be read can be retrieved using {{mIRC|$sock|$sock(name).rq) |
By default: | By default: | ||
Line 14: | Line 14: | ||
== Synopsis == | == Synopsis == | ||
− | <source lang="mIRC"> | + | <source lang="mIRC">/sockread [-fn] [numbytes] <%var|&binvar></source> |
− | /sockread [-fn] | ||
− | |||
− | </source> | ||
== Switches == | == Switches == | ||
− | + | {| class="wikitable" style="line-height: 25px; margin-left: 75px;" | |
− | + | |- | |
+ | ! Switch !! Description | ||
+ | |- | ||
+ | | '''f''' || When reading a terminated line (/sockread %var or /sockread -n &var), forces mIRC to fill the variable with whatever text is in the receive buffer, even if it does not end in a terminated line. | ||
+ | |- | ||
+ | | '''n''' || Reads a terminated line into a {{mIRC|binary variables|&binvars}}. If the incoming line does not contain a terminated line, no byte will be read into the {{mIRC|binary variables|&binvars}}, unless you specify the '''-f''' switch. | ||
+ | |} | ||
== Parameters == | == Parameters == | ||
− | + | {| class="wikitable" style="line-height: 25px; margin-left: 75px;" | |
− | + | |- | |
+ | ! Parameter !! Description | ||
+ | |- | ||
+ | | '''[numbytes]''' || The number of bytes to read from the receive buffer. | ||
+ | |- | ||
+ | | '''[%var/&binvar]''' || The name of the variable to read the socket buffer into. | ||
+ | |} | ||
== Reading == | == Reading == | ||
Line 34: | Line 43: | ||
b) you were reading into a %var and there is still a terminated line in the buffer waiting to be read. | b) you were reading into a %var and there is still a terminated line in the buffer waiting to be read. | ||
− | This means you will miss the last line if it | + | This means you will miss the last line if it does not end with a terminated line and you are reading line by line only. |
− | '''Note''' | + | '''Note''': It is possible to read such a last line inside the on sockclose event. |
+ | '''Note2''': Using SSL, on sockread might not be retriggered as it should, {{mIRC|on sockclose}} will be triggered too early with $sockerr sets to 3, you must read the receive buffer from that event | ||
− | It is important to note that the data received will vary | + | It is important to note that the data received will vary. Practically speaking, we receive several kilobytes per second, it is easy to assume that the data you want is going to be sent and received the same way and above all, the way you want, but that's incorrect, you might receive very small packet at a very small speed. |
A common situation when dealing with HTML is to check the source of the page you are working with, to identify something that is unlikley to change, and to use that as a reference. Doing this is not bad, but the way it is usually implemented by mIRC user is incorrect. | A common situation when dealing with HTML is to check the source of the page you are working with, to identify something that is unlikley to change, and to use that as a reference. Doing this is not bad, but the way it is usually implemented by mIRC user is incorrect. | ||
Line 60: | Line 70: | ||
} | } | ||
}</source> | }</source> | ||
− | If you do that, you cannot guarantee it will work 100% of the time. | + | If you do that, you cannot guarantee it will work 100% of the time, you cannot read the content of the received buffer, if the received buffer is filled with a few bytes and ends up being "this is my ref" when on sockread triggers, the if statement won't be true, for example here, the next time the event triggers, you might have a received buffer containing "erence:", but it might be "erence:\r\nI want that line" as well. |
− | + | This scenario is very unlikely to happen, because you are reading line by line, which is much much slower than reading the whole content of the received buffer and as such, the received buffer is filled by mIRC faster than your socket code reads it. But it is still possible. | |
+ | You can fix this by changing the logic of your event to use /sockread %a instead of /sockread -f %a. Indeed, not using the -f switch, mIRC will only read data if you have a terminated line in the received buffer, so if you check $sockbr, (the number of bytes read), you can /return in the event if it's 0 and wait for it to retrigger, hopfully this time a terminated line will be in the received buffer. If you do this change and still need to get the last non terminated line, you will need do so inside the on sockclose event, no problem otherwise: | ||
− | + | '''Note''': In this case we could ditch the "if ($sockbr == 0) return" because %a wouldn't be equal to "this is my reference:" anyway, but you could be checking that %a is $null there, so generally speaking you should use it in this situation | |
<source lang="mIRC"> | <source lang="mIRC"> | ||
Line 70: | Line 81: | ||
var %a | var %a | ||
sockread %a | sockread %a | ||
+ | if ($sockbr == 0) return | ||
+ | ;guaranteed to get %a with a full line. | ||
if (%a == this is my reference:) { | if (%a == this is my reference:) { | ||
... | ... | ||
Line 75: | Line 88: | ||
}</source> | }</source> | ||
− | + | Another solution consists in making a buffer by yourself and adding what you are reading to it, until you get the correct portion you want (a terminated line in this example). | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | Another solution consists in making a buffer by yourself and adding what you are reading to it, until you get the correct portion you want (a terminated line in | ||
If you are reading the whole content of the received buffer with one /sockread using binary variable or just large portion of the received buffer in a binary variable, you are more likely to see the | If you are reading the whole content of the received buffer with one /sockread using binary variable or just large portion of the received buffer in a binary variable, you are more likely to see the | ||
− | issue because you are basically reading the buffer as fast as mIRC fills it (or faster than line by line for large portion). The same solutions exists for binary variables, use /sockread -n to read a terminated line into the binvar, check $sockbr to make sure you read something | + | issue because you are basically reading the buffer as fast as mIRC fills it (or faster than line by line for large portion). The same solutions exists for binary variables, use /sockread -n to read a terminated line into the binvar, check $sockbr to make sure you read something (cause if so, a whole line has been read). |
* Reading from the receive buffer | * Reading from the receive buffer | ||
Line 145: | Line 126: | ||
</source> | </source> | ||
− | '''General Note''': | + | '''General Note''': if you want to avoid any issue, you should write the whole source to a file and then parse that file, this might be easier. |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
== Example == | == Example == | ||
Line 178: | Line 136: | ||
'''Note2''': too long line will produce an error. | '''Note2''': too long line will produce an error. | ||
− | '''Note3''': Using SSL, the | + | '''Note3''': Using SSL, the sockread might not be triggered though there are still datas to be read, you must read the rest in the on sockclose event. |
<source lang="mIRC">ON *:SOCKREAD:mySocket:{ | <source lang="mIRC">ON *:SOCKREAD:mySocket:{ | ||
Line 192: | Line 150: | ||
</source> | </source> | ||
− | '''Note''': | + | '''Note''': if the last line in the source does not end with a terminated line, it won't be read by that event, you might want to read that last line inside the on sockclose event. We can't use -f on sockread because it would allow the code to display whatever is in the buffer even if no terminated line is present. |
If you ever worked with HTTP 1.1, you know that it can send data in chunk, here is a way to write the real content to a file: | If you ever worked with HTTP 1.1, you know that it can send data in chunk, here is a way to write the real content to a file: | ||
Line 218: | Line 176: | ||
else { | else { | ||
var %a | var %a | ||
− | + | ||
− | ; | + | ;when we start, the next line is the chunk size, but after reading a chunk, we must parse the $crlf ending that chunk |
− | while ($sockbr) && (%a == $null) { sockread %a } | + | ;so if we read and %a is $null, it means we are after the start, we try to read the next line, if we can't find the next chunk in the current receive buffer, we return and allow the event to retrigger with more data. |
+ | sockread -f %a | ||
+ | while ($sockbr) && (%a == $null) { sockread -f %a } | ||
if (!$sockbr) || (%a == $null) return | if (!$sockbr) || (%a == $null) return | ||
;last chunk | ;last chunk |