From WikiChip
Editing mirc/sockets/tcp

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 title|TCP Sockets}}{{Preknow|This article assumes that you have intermediate to advanced knowledge of the [[mIRC Scripting Language]] and familiarity with {{mIRC|on events}} and {{mIRC|aliases|custom aliases}}.}}
+
{{mIRC Guide}}
 +
{{Preknow|This article assumes that you have intermediate to advanced knowledge of the [[mIRC Scripting Language]] and familiarity with [[On events - mIRC|on events]] and [[Aliases - mIRC|custom aliases]].}}
  
mIRC has built-in support for '''TCP Sockets'''. This tutorial is the '''TCP Sockets''' continuation of the {{mIRC|sockets|Sockets (Intro) tutorial}}. If you haven't read that, please do so first before moving on to this one.
+
This tutorial is the '''TCP Sockets''' continuation of the [[Sockets - mIRC|Sockets (Intro) tutorial]]. If you haven't read that, please do so first before moving on to this one.
  
 
Now that you have some familiarity with the different types of sockets we can go into the scripting aspect of things. The most common task scripters want to perform is retrieving a piece data from some website.
 
Now that you have some familiarity with the different types of sockets we can go into the scripting aspect of things. The most common task scripters want to perform is retrieving a piece data from some website.
Line 8: Line 9:
  
 
== Creating a Connection ==
 
== Creating a Connection ==
Before we can do anything else we must first create a new connection to a specific address on a given port. This is done using the {{mIRC|/sockopen}} command:
+
Before we can do anything else we must first create a new connection to a specific address on a given port. The syntax to do this:
  
 
<syntaxhighlight lang="mirc">sockopen <handle> <address> <port></syntaxhighlight>
 
<syntaxhighlight lang="mirc">sockopen <handle> <address> <port></syntaxhighlight>
Line 20: Line 21:
  
 
=== IPv4 vs. IPv6 Sockets ===
 
=== IPv4 vs. IPv6 Sockets ===
The /sockopen command is directly influenced by the Ipv6 mode you have going on. Check {{mIRC|Ipv6|this page}} for more informations about IPv6.
+
The /sockopen command is directly influenced by the type of connection you have going on (I.e. /server -4/-6). When in standard IPv4 mode, /sockopen can only operate in IPv4 mode. It is not possible to make IPv6 sockets. When in IPv6, /sockopen will default to IPv6 addresses only. By going to the Option Dialog:
 +
 
 +
(Alt+O) -> Connect -> Options -> Ports... -> [X] Prioritize IPv6 over IPv4
 +
 
 +
Checking that checkbox will allow you to create IPv4 connections as well by telling mIRC to fall back to IPv4 if IPv6 failed.
 +
 
 +
'''Note:''' There is currently no convenient way to do this only using the /sockopen command.
  
 
=== Connection Example ===
 
=== Connection Example ===
Line 31: Line 38:
 
}</syntaxhighlight>
 
}</syntaxhighlight>
  
The above alias will create a socket by the name "example1". We can use that name to manipulate our socket later on. As a precaution, in order to not attempt to open an already opened socket, we will close it. If the socket is not open, mIRC will simply do nothing. In the advanced part of this tutorial we will explain how to handle this situation more gracefully by creating dynamic names which will give us the ability to create as many sockets as we need.
+
The above alias will create a socket by the name "example1". We can use that name to manipulate our socket late on. As a precaution, in order to not attempt to open an already opened socket, we will close it. If the socket is not open, mIRC will simply do nothing. In the advanced part of this tutorial we will explain how to handle this situation more gracefully by creating dynamic names which will give us the ability to create as many sockets as we need.
  
 
<syntaxhighlight lang="mirc">alias example1 {
 
<syntaxhighlight lang="mirc">alias example1 {
Line 55: Line 62:
  
 
== The Socket Mark ==
 
== The Socket Mark ==
In the example above we introduced another command, the {{mIRC|/sockmark}} command. The {{mIRC|/sockmark}} command lets you store some text for that socket which can easily be retrieved using the {{mIRC|$sock|$sock().mark}} identifier later on. This is a better alternative to using global variables (or any other kind of global storage method) because you don't need to clean it up later. The socket mark goes away automatically with the socket when it is closed.
+
In the example above we introduced another command, the [[/sockmark command - mIRC|/sockmark]] command. The [[/sockmark command - mIRC|/sockmark]] command lets you store some text for that socket which can easily be retrieved using the [[$sock identifier - mIRC|$sock().mark]] identifier later on. This is a better alternative to using a global variables (or any other kind of global storage method) and having to clean it up later. The socket mark goes away automatically with the socket.
  
 
<syntaxhighlight lang="mirc">sockmark <handle> <value>
 
<syntaxhighlight lang="mirc">sockmark <handle> <value>
Line 61: Line 68:
 
sockmark <handle></syntaxhighlight>
 
sockmark <handle></syntaxhighlight>
  
The socket mark is restricted to the same line limit as the rest of mIRC (just under 4,150 bytes). A {{mirc|wildcard}} pattern can be used in the handle parameter to set the value of multiple sockets at once.
+
The socket mark is restricted to the same line limit as the rest of mIRC (just under 4,150 bytes). A wildcard pattern can be used in the handle parameter to set the value of multiple sockets at once.
  
 
<syntaxhighlight lang="mirc">; Our socket mark value:
 
<syntaxhighlight lang="mirc">; Our socket mark value:
Line 67: Line 74:
  
 
== Transmitting a Request After a Successful Connection ==
 
== Transmitting a Request After a Successful Connection ==
When a successful connection to the remote end-point has been established, the {{mIRC|on sockopen}} event will trigger. Inside the on sockopen event we must send our initial request which would depend on what our script wants to do. A typical script that utilizes the HTTP protocol must send its headers in this event.
+
When a successful connection to the remote end-point has been established, the on sockopen event will trigger. Inside the on sockopen event we must send our initial request which would depend on what our script wants to do. A typical script that utilizes the HTTP protocol must send its headers in this event.
  
 
'''Note:''' If a connection failed, on sockopen will also trigger, the difference this time is that $sockerr is set, see the Error Handling section below for more informations.
 
'''Note:''' If a connection failed, on sockopen will also trigger, the difference this time is that $sockerr is set, see the Error Handling section below for more informations.
  
The typical syntax for the on sockopen event is:  
+
The syntax for the on sockopen event is:  
  
 
<syntaxhighlight lang="mirc">on *:sockopen:<handle>: {
 
<syntaxhighlight lang="mirc">on *:sockopen:<handle>: {
Line 77: Line 84:
 
}</syntaxhighlight>
 
}</syntaxhighlight>
  
As we said before, from within the sockopen event we must send our request to the remote end-point. To send data to the remote end-point through the socket we use the {{mIRC|/sockwrite}} command. The sockwrite command has the following syntax:
+
As we said before, from within the sockopen event we must send our request to the remote end-point. To send data to the remote end-point through the socket we use the /sockwrite command. The sockwrite command has the following syntax:
  
 
<syntaxhighlight lang="mirc">sockwrite [-tn] <name> <text|%var|&binvar>
 
<syntaxhighlight lang="mirc">sockwrite [-tn] <name> <text|%var|&binvar>
Line 83: Line 90:
 
sockwrite -b[tn] <name> <numbytes> <text|%var|&binvar></syntaxhighlight>
 
sockwrite -b[tn] <name> <numbytes> <text|%var|&binvar></syntaxhighlight>
  
By default, all space-delimited tokens that begin with the '&' symbol are treated as binary variables. The -t switch can be used to make the /sockwrite command treat it all as plain text instead.
+
By default, all space-delimited tokens that begin with the & symbol are treated as binary variables. The -t switch can be used to make the /sockwrite command treat it all as plain text instead.
  
 
=== The Sockwrite -n Switch and $crlf ===
 
=== The Sockwrite -n Switch and $crlf ===
Line 116: Line 123:
  
 
Understanding this concept is important to understanding how to send data correctly via protocols like HTTP.
 
Understanding this concept is important to understanding how to send data correctly via protocols like HTTP.
 
=== /sockwrite's limit ===
 
 
Just like anywhere in the mIRC Scripting language, there is a limit on the number of bytes you can send using /sockwrite. A socket in mIRC has two buffers, one for the receiving and one for the sending.
 
The sending buffer is limited to 16384 bytes. /sockwrite will produce an error if you try to add more in the buffer. However, if the buffer is empty, it won't produce an error and will work.
 
 
In a typical script using HTTP and the {{mIRC|TCP Sockets#POST_vs_GET.3F|GET method}} to grab something from a website, it's unlikely that you will reach this limit but note that when using {{mIRC|TCP Sockets#POST_vs_GET.3F|POST}}, it's more likely to reach that limit, you can find an example on how to workaround this by using the on sockwrite event {{mIRC|on events/on sockwrite#Examples|here}}
 
  
 
=== Sending Data Example ===
 
=== Sending Data Example ===
Line 160: Line 160:
 
alias urlEncode return $regsubex($1, /(\W)/g, $+(%, $base($asc(\t), 10, 16, 2)))
 
alias urlEncode return $regsubex($1, /(\W)/g, $+(%, $base($asc(\t), 10, 16, 2)))
 
; Decode encoded URLs
 
; Decode encoded URLs
alias urlDecode return $regsubex($replace($1, +, $chr(32)), /%([A-F\d]{2})/gi, $chr($base(\1, 16, 10)))
+
alias urlDecode return $regsubex($replace($1, +, $chr(32)), /%([A-F\d]{2})/gi, $chr($base(\1, 16, 10)))</syntaxhighlight>
 
 
; Since mIRC 7.x, mIRC is Unicode, since the percent encoding is byte based, you must decode the byte to utf8 with $utfdecode after decoding the percent encoding:
 
 
 
alias urlDecode return $utfdecode($regsubex($replace($1, +, $chr(32)), /%([A-F\d]{2})/gi, $chr($base(\1, 16, 10))))
 
</syntaxhighlight>
 
  
 
Consider the following example:
 
Consider the following example:
Line 213: Line 208:
  
 
== Reading Incoming Data ==
 
== Reading Incoming Data ==
Once the server receives your request, it will send the response back to you. This will trigger the {{mIRC|on events/on sockread|on sockread}} event. The basic syntax of the on sockread event is:
+
Once the server receives your request, it will send the response back to you. This will trigger the on sockread event. The basic syntax of the on sockread event is:
  
 
<syntaxhighlight lang="mirc">on *:sockread:<handle>: {
 
<syntaxhighlight lang="mirc">on *:sockread:<handle>: {
Line 219: Line 214:
 
}</syntaxhighlight>
 
}</syntaxhighlight>
  
The on sockread will most likely be the hardest and longest part of your code. When the on sockread event triggers, you have to read the data and decide what to do with it. If your script just needs some information from that page you will have to find and parse the appropriate line.  
+
The on sockread will most likely be the hardest and longest part of your code. When the on sockread triggers, you have to read the data and decide what to do with it. If your script just needs some information from that page you will have to find and parse the appropriate line.  
  
 
When it comes to HTTP, the data you will receive from the server will contain a header followed by a blank line which will be followed by the content of the page. The content of the page will look identical to that text you find when you right click on a web page and click on view source code.
 
When it comes to HTTP, the data you will receive from the server will contain a header followed by a blank line which will be followed by the content of the page. The content of the page will look identical to that text you find when you right click on a web page and click on view source code.
  
Reading data that has been sent from the server is done with the {{mIRC|/sockread}} command. That command is powerful because it allows you to read the data in a lot of ways, with HTTP, you'll likely want to get the data line by line.
+
Reading data that has been sent from the server is done with the /sockread command. That command is powerful because it allows you to read the data in a lot of ways, with HTTP, you'll likely want to get the data line by line.
  
 
To read a single line from the socket, we use the /sockread command that way:
 
To read a single line from the socket, we use the /sockread command that way:
Line 268: Line 263:
 
=== Error Handling ===
 
=== Error Handling ===
 
Errors happen! It's a fact of life. It is your responsibility to check for them and gracefully handle them! The $sockerr identifier must be checked after every socket operations. If the value of $sockerr is greater than zero, an error has occurred and we MUST stop whatever it is we were going to do with the socket, cleanup, perhaps display an error message etc.
 
Errors happen! It's a fact of life. It is your responsibility to check for them and gracefully handle them! The $sockerr identifier must be checked after every socket operations. If the value of $sockerr is greater than zero, an error has occurred and we MUST stop whatever it is we were going to do with the socket, cleanup, perhaps display an error message etc.
Remember, inside the on sockopen event, $sockerr allows you to know if the connection was sucessful or not.
+
Inside the on sockopen event, $socker allows you to know if the connection was sucessful or not.
  
 
A basic example would look like this:
 
A basic example would look like this:
Line 332: Line 327:
  
 
==== Example 2 (YouTube, Continue) ====
 
==== Example 2 (YouTube, Continue) ====
If you tried to print the youtube page we did (http://www.youtube.com/watch?v=FDw0NdhK6QU) you will quickly realize how long the youtube webpage is. For this reason I will not show it here. The way we parse that page is very much like the one we did for the first example:
+
If you tried to p rint the youtube page we did (http://www.youtube.com/watch?v=FDw0NdhK6QU) you will quickly realize how long the youtube webpage is. For this reason I will not show it here. The way we parse that page is very much like the one we did for the first example:
  
 
<syntaxhighlight lang="mirc">
 
<syntaxhighlight lang="mirc">
Line 346: Line 341:
 
     sockread %x
 
     sockread %x
 
     ; make sure it's a number
 
     ; make sure it's a number
    ; the (*UTF8) in the expression is required for the regex engine to interpret utf8 sequences, which is what mIRC use (here for a $chr(160))
+
     if ($regex(%x,/^ *([\d,]+)$/)) {
     if ($regex(%x,/(*UTF8)^ *([\d\xA0]+)/)) {
+
      ; parse the view count
       set %view. $+ $sockname $replace($regml(1),$chr(160),$chr(32))
+
       set %view. $+ $sockname $regml(1)
 
     }
 
     }
 
   }
 
   }
  ;if we find the username of the uploader, we are done
+
   else if (*Uploaded by* iswm %x) {
   else if ($regex(%x,/<\/a><a ?href="\/user\/([^"]+)/)) {  
 
 
     ; print out the info
 
     ; print out the info
 
     echo -a Title: $($+(%, title., $sockname), 2) $&
 
     echo -a Title: $($+(%, title., $sockname), 2) $&
       Uploader: $regml(1) Views: $($+(%, view., $sockname), 2)
+
       $noHTML(%x) Views: $($+(%, view., $sockname), 2)
 
     ; cleanup
 
     ; cleanup
 
     unset %*. $+ $sockname
 
     unset %*. $+ $sockname
Line 373: Line 367:
 
'''Note:''' Only the remote end-port, not you, can trigger this event.
 
'''Note:''' Only the remote end-port, not you, can trigger this event.
  
[[Category:mIRC|sockets tcp]]
+
[[Category:mIRC]]

Please note that all contributions to WikiChip may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see WikiChip:Copyrights for details). Do not submit copyrighted work without permission!

Cancel | Editing help (opens in new window)