]> gitweb.factorcode.org Git - factor.git/blob - basis/io/sockets/sockets-docs.factor
Squashed commit of the following:
[factor.git] / basis / io / sockets / sockets-docs.factor
1 USING: help.markup help.syntax io io.backend threads
2 strings byte-arrays continuations destructors quotations ;
3 IN: io.sockets
4
5 ARTICLE: "network-addressing" "Address specifiers"
6 "The networking words are quite general and work with " { $emphasis "address specifiers" } " rather than concrete concepts such as host names. There are four types of address specifiers."
7 $nl
8 "Unix domain sockets:"
9 { $subsections
10     local
11     <local>
12 }
13 "Internet host name/port number pairs; the host name is resolved to an IPv4 or IPv6 address using the operating system's resolver:"
14 { $subsections
15     inet
16     <inet>
17 }
18 "IPv4 addresses, with no host name resolution:"
19 { $subsections
20     inet4
21     <inet4>
22 }
23 "IPv6 addresses, with no host name resolution:"
24 { $subsections
25     inet6
26     <inet6>
27 }
28 "While the " { $link inet } " addressing specifier is capable of performing name lookups when passed to " { $link <client> } ", sometimes it is necessary to look up a host name without making a connection:"
29 { $subsections resolve-host } ;
30
31 ARTICLE: "network-connection" "Connection-oriented networking"
32 "Network connections can be established with this word:"
33 { $subsections
34     <client>
35     with-client
36 }
37 "The local address of a client socket can be controlled with this word:"
38 { $subsections
39     with-local-address
40 }
41 "Connection-oriented network servers are implemented by first opening a server socket, then waiting for connections:"
42 { $subsections
43     <server>
44     accept
45 }
46 "Server sockets are closed by calling " { $link dispose } "."
47 $nl
48 "Address specifiers have the following interpretation with connection-oriented networking words:"
49 { $list
50     { { $link local } " - Unix domain stream sockets on Unix systems" }
51     { { $link inet } " - a TCP/IP connection to a host name/port number pair which can resolve to an IPv4 or IPv6 address" }
52     { { $link inet4 } " - a TCP/IP connection to an IPv4 address and port number; no name lookup is performed" }
53     { { $link inet6 } " - a TCP/IP connection to an IPv6 address and port number; no name lookup is performed" }
54 }
55 "The " { $vocab-link "io.servers" } " library defines high-level wrappers around " { $link <server> } " which makes it easy to listen for IPv4, IPv6 and secure socket connections simultaneously, perform logging, and optionally only allow connections from the loopback interface."
56 $nl
57 "The " { $vocab-link "io.sockets.secure" } " vocabulary implements secure, encrypted sockets via SSL and TLS." ;
58
59 ARTICLE: "network-packet" "Packet-oriented networking"
60 "A packet-oriented socket can be opened with this word:"
61 { $subsections <datagram> }
62 "Packets can be sent and received with a pair of words:"
63 { $subsections
64     send
65     receive
66 }
67 "Packet-oriented sockets are closed by calling " { $link dispose } "."
68 $nl
69 "Address specifiers have the following interpretation with packet-oriented networking words:"
70 { $list
71     { { $link local } " - Unix domain datagram sockets on Unix systems" }
72     { { $link inet4 } " - a TCP/IP connection to an IPv4 address and port number; no name lookup is performed" }
73     { { $link inet6 } " - a TCP/IP connection to an IPv6 address and port number; no name lookup is performed" }
74 }
75 "The " { $link inet } " address specifier is not supported by the " { $link send } " word because a single host name can resolve to any number of IPv4 or IPv6 addresses, therefore there is no way to know which address should be used. Applications should call " { $link resolve-host } " then use some kind of strategy to pick the correct address (for example, by sending a packet to each one and waiting for a response, or always assuming IPv4)." ;
76
77 ARTICLE: "network-examples" "Networking examples"
78 "Send some bytes to a remote host:"
79 { $code
80     "USING: io io.encodings.ascii io.sockets strings ;"
81     "\"myhost\" 1033 <inet> ascii"
82     "[ B{ 12 17 102 } write ] with-client"
83 }
84 "Look up the IP addresses associated with a host name:"
85 { $code "USING: io.sockets ;" "\"www.apple.com\" 80 <inet> resolve-host ." } ;
86
87 ARTICLE: "network-streams" "Networking"
88 "Factor supports connection-oriented and packet-oriented communication over a variety of protocols:"
89 { $list
90     "TCP/IP and UDP/IP, over IPv4 and IPv6"
91     "Unix domain sockets (Unix only)"
92 }
93 { $subsections
94     "network-examples"
95     "network-addressing"
96     "network-connection"
97     "network-packet"
98 }
99 { $vocab-subsection "Secure sockets (SSL, TLS)" "io.sockets.secure" }
100 { $see-also "io.pipes" } ;
101
102 ABOUT: "network-streams"
103
104 HELP: local
105 { $class-description "Local address specifier for Unix domain sockets on Unix systems. The " { $snippet "path" } " slot holds the path name of the socket. New instances are created by calling " { $link <local> } "." }
106 { $examples
107     { $code "\"/tmp/.X11-unix/0\" <local>" }
108 } ;
109
110 HELP: inet
111 { $class-description "Host name/port number specifier for TCP/IP and UDP/IP connections. The " { $snippet "host" } " and " { $snippet "port" } " slots hold the host name and port name or number, respectively. New instances are created by calling " { $link <inet> } "." }
112 { $notes
113     "This address specifier is only supported by " { $link <client> } ", which calls " { $link resolve-host }  " to obtain a list of IP addresses associated with the host name, and attempts a connection to each one in turn until one succeeds. Other network words do not accept this address specifier, and " { $link resolve-host } " must be called directly; it is then up to the application to pick the correct address from the (possibly several) addresses associated to the host name."
114 }
115 { $examples
116     { $code "\"www.apple.com\" 80 <inet>" }
117 } ;
118
119 HELP: <inet>
120 { $values { "host" "a host name" } { "port" "a port number" } { "inet" inet } }
121 { $description "Creates a new " { $link inet } " address specifier." } ;
122
123 HELP: inet4
124 { $class-description "IPv4 address/port number specifier for TCP/IP and UDP/IP connections. The " { $snippet "host" } " and " { $snippet "port" } " slots hold the IPv4 address and port number, respectively. New instances are created by calling " { $link <inet4> } "." }
125 { $notes "Most applications do not operate on IPv4 addresses directly, and instead should use the " { $link inet } " address specifier, or call " { $link resolve-host } "." }
126 { $examples
127     { $code "\"127.0.0.1\" 8080 <inet4>" }
128 } ;
129
130 HELP: <inet4>
131 { $values { "host" "an IPv4 address" } { "port" "a port number" } { "inet4" inet4 } }
132 { $description "Creates a new " { $link inet4 } " address specifier." } ;
133
134 HELP: inet6
135 { $class-description "IPv6 address/port number specifier for TCP/IP and UDP/IP connections. The " { $snippet "host" } " and " { $snippet "port" } " slots hold the IPv6 address and port number, respectively. New instances are created by calling " { $link <inet6> } "." }
136 { $notes "Most applications do not operate on IPv6 addresses directly, and instead should use the " { $link inet } " address specifier, or call " { $link resolve-host } "." }
137 { $examples
138     { $code "\"::1\" 8080 <inet6>" }
139 } ;
140
141 HELP: <inet6>
142 { $values { "host" "an IPv6 address" } { "port" "a port number" } { "inet6" inet6 } }
143 { $description "Creates a new " { $link inet6 } " address specifier." } ;
144
145 HELP: <client>
146 { $values { "remote" "an address specifier" } { "encoding" "an encding descriptor" } { "stream" "a bidirectional stream" } { "local" "an address specifier" } }
147 { $description "Opens a network connection and outputs a bidirectional stream using the given encoding, together with the local address the socket was bound to." }
148 { $errors "Throws an error if the connection cannot be established." }
149 { $notes "The " { $link with-client } " word is easier to use in most situations." }
150 { $examples
151     { $code "\"www.apple.com\" 80 <inet> utf8 <client>" }
152 } ;
153
154 HELP: with-client
155 { $values { "remote" "an address specifier" } { "encoding" "an encoding descriptor" } { "quot" quotation } }
156 { $description "Opens a network connection and calls the quotation in a new dynamic scope with " { $link input-stream } " and " { $link output-stream } " rebound to the network streams. The local address the socket is connected to is stored in the " { $link local-address } " variable, and the remote address is stored in the " { $link remote-address } " variable." }
157 { $errors "Throws an error if the connection cannot be established." } ;
158
159 HELP: <server>
160 { $values  { "addrspec" "an address specifier" } { "encoding" "an encoding descriptor" } { "server" "a handle" } }
161 { $description
162     "Begins listening for network connections to a local address. Server objects respond to two words:"
163     { $list
164         { { $link dispose } " - stops listening on the port and frees all associated resources" }
165         { { $link accept } " - blocks until there is a connection, and returns a stream of the encoding passed to the constructor" }
166     }
167 }
168 { $notes
169     "To start a TCP/IP server which listens for connections from any host, use an address specifier returned by the following code, where 1234 is the desired port number:"
170     { $code "f 1234 <inet> resolve-host" }
171     "To start a server which listens for connections from the loopback interface only, use an address specifier returned by the following code, where 1234 is the desired port number:"
172     { $code "\"localhost\" 1234 <inet> resolve-host" }
173     "Since " { $link resolve-host } " can return multiple address specifiers, your server code must listen on them all to work properly. The " { $vocab-link "io.servers" } " vocabulary can be used to help with this."
174     $nl
175     "To start a TCP/IP server which listens for connections on a randomly-assigned port, set the port number in the address specifier to 0, and then read the " { $snippet "addr" } " slot of the server instance to obtain the actual port number it is listening on:"
176     { $unchecked-example
177         "f 0 <inet4> ascii <server>"
178         "[ addr>> . ] [ dispose ] bi"
179         "T{ inet4 f \"0.0.0.0\" 58901 }"
180     }
181 }
182 { $errors "Throws an error if the address is already in use, or if it if the system forbids access." } ;
183
184 HELP: accept
185 { $values { "server" "a handle" } { "client" "a bidirectional stream" } { "remote" "an address specifier" } }
186 { $description "Waits for a connection to a server socket created by " { $link <server> } ", and outputs a bidirectional stream when the connection has been established. The encoding of this stream is the one that was passed to the server constructor." }
187 { $errors "Throws an error if the server socket is closed or otherwise is unavailable." } ;
188
189 HELP: <datagram>
190 { $values { "addrspec" "an address specifier" } { "datagram" "a handle" } }
191 { $description "Creates a datagram socket bound to a local address. Datagram socket objects responds to three words:"
192     { $list
193         { { $link dispose } " - stops listening on the port and frees all associated resources" }
194         { { $link receive } " - waits for a packet" }
195         { { $link send } " - sends a packet" }
196     }
197 }
198 { $notes
199     "To accept UDP/IP packets from any host, use an address specifier where the host name is set to " { $link f } ":"
200     { $code "f 1234 <inet4> <datagram>" }
201     "To create a datagram socket bound to a randomly-assigned port, set the port number in the address specifier to 0, and then read the " { $snippet "addr" } " slot of the datagram instance to obtain the actual port number it is bound to:"
202     { $code "f 0 <inet4> <datagram>" }
203     "To accept UDP/IP packets from the loopback interface only, use an address specifier like the following:"
204     { $code "\"127.0.0.1\" 1234 <inet4> <datagram>s" }
205     "Since " { $link resolve-host } " can return multiple address specifiers, your code must create a datagram socket for each one and co-ordinate packet sending accordingly."
206 }
207 { $errors "Throws an error if the port is already in use, or if the OS forbids access." } ;
208
209 HELP: receive
210 { $values { "datagram" "a datagram socket" } { "packet" byte-array } { "addrspec" "an address specifier" } }
211 { $description "Waits for an incoming packet on the given datagram socket. Outputs the packet data, as well as the sender's address." }
212 { $errors "Throws an error if the packet could not be received." } ;
213
214 HELP: send
215 { $values { "packet" byte-array } { "addrspec" "an address specifier" } { "datagram" "a datagram socket" } }
216 { $description "Sends a packet to the given address." }
217 { $errors "Throws an error if the packet could not be sent." } ;
218
219 HELP: resolve-host
220 { $values { "addrspec" "an address specifier" } { "seq" "a sequence of address specifiers" } }
221 { $description "Resolves host names to IP addresses." } ;
222
223 HELP: with-local-address
224 { $values { "addr" "an " { $link inet4 } " or " { $link inet6 } " address specifier" } { "quot" quotation } }
225 { $description "Client sockets opened within the scope of the quotation passed to this combinator will have their local address bound to the given address." }
226 { $examples
227   { "Binds the local address of a newly created client socket within the quotation to 127.0.0.1."
228     "This ensures that all traffic originates from the given address (the port is choosen by the TCP stack)." }
229   { $code "\"127.0.0.1\" 0 <inet4> [ ] with-local-address" }
230   $nl
231   { "Binds the local address of a newly created client socket within the quotation to the local address 192.168.0.1 and the local port 23000. "
232     "Be aware that you can only have one client socket with the same local address at a time or else an I/O error (\"address already in use\") will be thrown."
233   }
234   { $code "\"192.168.0.1\" 23000 <inet4> [ ] with-local-address" }
235 } ;