From f6860a970ea80c388730cea6c5866ce03673aaa7 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Wed, 1 Mar 2017 16:02:29 +0800 Subject: [PATCH 1/7] doc: various improvements to net.md * Improve general description of the module, specifically, explain that it provides TCP or local communications (domain sockets on UNIX, named pipes on Windows) functionalities. * Improve explanation of `allowHalfOpen` * Nest the overloaded `server.listen()` API in a list, explain the common arguments and notes in the same place. Some minor improvements: * Add description to the `net.Server` constructor * Add type annotations to `server.listen()` * Add contexts to method links --- doc/api/net.md | 272 +++++++++++++++++++++++++++---------------------- 1 file changed, 152 insertions(+), 120 deletions(-) diff --git a/doc/api/net.md b/doc/api/net.md index 3465ece47be9c0..194cdfc198c4f6 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -2,9 +2,14 @@ > Stability: 2 - Stable -The `net` module provides you with an asynchronous network wrapper. It contains -functions for creating both servers and clients (called streams). You can include -this module with `require('net');`. +The `net` module provides an asynchronous network API for creating +servers ([`net.Server`][]) and clients ([`net.Socket`][]) that implement TCP +or local communications (domain sockets on UNIX, named pipes on Windows). +It can be accessed using: + +```js +const net = require('net'); +``` ## Class: net.Server -Emitted when the server has been bound after calling `server.listen`. +Emitted when the server has been bound after calling [`server.listen()`][]. ### server.address() * `handle` {Object} -* `backlog` {number} -* `callback` {Function} - -The `handle` object can be set to either a server or socket (anything -with an underlying `_handle` member), or a `{fd: }` object. +* `backlog` {number} Common parameter of [`server.listen()`][] functions +* `callback` {Function} Common parameter of [`server.listen()`][] functions -This will cause the server to accept connections on the specified -handle, but it is presumed that the file descriptor or handle has -already been bound to a port or domain socket. +Start a server listening for connections on a given `handle` that has +already been bound to a port, a UNIX domain socket, or a Windows named pipe. -Listening on a file descriptor is not supported on Windows. +The `handle` object can be either a server, a socket (anything with an +underlying `_handle` member), or an object with a `fd` member that is a valid file descriptor. -This function is asynchronous. When the server has been bound, -[`'listening'`][] event will be emitted. -The last parameter `callback` will be added as a listener for the -[`'listening'`][] event. +*Note*: Listening on a file descriptor is not supported on Windows. -The parameter `backlog` behaves the same as in -[`server.listen([port][, hostname][, backlog][, callback])`][`server.listen(port, host, backlog, callback)`]. - -### server.listen(options[, callback]) +#### server.listen(options[, callback]) -* `options` {Object} - Required. Supports the following properties: - * `port` {number} - Optional. - * `host` {string} - Optional. - * `backlog` {number} - Optional. - * `path` {string} - Optional. - * `exclusive` {boolean} - Optional. -* `callback` {Function} - Optional. +* `options` {Object} Required. Supports the following properties: + * `port` {number} Optional. + * `host` {string} Optional. + * `path` {string} Optional. Will be ignored if `port` is specified. + * `backlog` {number} Optional. Common parameter of [`server.listen()`][] + functions + * `exclusive` {boolean} Optional. Default to `false` +* `callback` {Function} Optional. Common parameter of [`server.listen()`][] + functions -The `port`, `host`, and `backlog` properties of `options`, as well as the -optional callback function, behave as they do on a call to +If `port` is specified, it behaves the same as [`server.listen([port][, hostname][, backlog][, callback])`][`server.listen(port, host, backlog, callback)`]. -Alternatively, the `path` option can be used to specify a UNIX socket. +Otherwise, if `path` is specified, it behaves the same as +[`server.listen(path[, backlog][, callback])`][`server.listen(path, backlog, callback)`]. +If none of them is specified, an error will be thrown. If `exclusive` is `false` (default), then cluster workers will use the same underlying handle, allowing connection handling duties to be shared. When @@ -175,24 +226,17 @@ server.listen({ }); ``` -*Note*: The `server.listen()` method may be called multiple times. Each -subsequent call will *re-open* the server using the provided options. - -### server.listen(path[, backlog][, callback]) +#### server.listen(path[, backlog][, callback]) -* `path` {string} -* `backlog` {number} -* `callback` {Function} +* `path` {String} +* `backlog` {number} Common parameter of [`server.listen()`][] functions +* `callback` {Function} Common parameter of [`server.listen()`][] functions Start a local socket server listening for connections on the given `path`. -This function is asynchronous. When the server has been bound, -[`'listening'`][] event will be emitted. The last parameter `callback` -will be added as a listener for the [`'listening'`][] event. - On UNIX, the local domain is usually known as the UNIX domain. The path is a filesystem path name. It gets truncated to `sizeof(sockaddr_un.sun_path)` bytes, decreased by 1. It varies on different operating system between 91 and @@ -214,19 +258,22 @@ net.createServer().listen( path.join('\\\\?\\pipe', process.cwd(), 'myctl')) ``` -The parameter `backlog` behaves the same as in -[`server.listen([port][, hostname][, backlog][, callback])`][`server.listen(port, host, backlog, callback)`]. - -*Note*: The `server.listen()` method may be called multiple times. Each -subsequent call will *re-open* the server using the provided options. - -### server.listen([port][, hostname][, backlog][, callback]) +#### server.listen([port][, host][, backlog][, callback]) +* `port` {number} +* `host` {string} +* `backlog` {number} Common parameter of [`server.listen()`][] functions +* `callback` {Function} Common parameter of [`server.listen()`][] functions -Begin accepting connections on the specified `port` and `hostname`. If the -`hostname` is omitted, the server will accept connections on the +Start a TCP server listening for connections on the given `port` and `host`. + +If `port` is omitted or is 0, the operating system will assign a random +port, which can be retrieved by using `server.address().port` +after the [`'listening'`][] event has been emitted. + +If `host` is omitted, the server will accept connections on the [unspecified IPv6 address][] (`::`) when IPv6 is available, or the [unspecified IPv4 address][] (`0.0.0.0`) otherwise. @@ -234,40 +281,6 @@ Begin accepting connections on the specified `port` and `hostname`. If the [unspecified IPv6 address][] (`::`) may cause the `net.Server` to also listen on the [unspecified IPv4 address][] (`0.0.0.0`). -Omit the port argument, or use a port value of `0`, to have the operating system -assign a random port, which can be retrieved by using `server.address().port` -after the `'listening'` event has been emitted. - -Backlog is the maximum length of the queue of pending connections. -The actual length will be determined by the OS through sysctl settings such as -`tcp_max_syn_backlog` and `somaxconn` on Linux. The default value of this -parameter is 511 (not 512). - -This function is asynchronous. When the server has been bound, -[`'listening'`][] event will be emitted. The last parameter `callback` -will be added as a listener for the [`'listening'`][] event. - -One issue some users run into is getting `EADDRINUSE` errors. This means that -another server is already running on the requested port. One way of handling this -would be to wait a second and then try again: - -```js -server.on('error', (e) => { - if (e.code == 'EADDRINUSE') { - console.log('Address in use, retrying...'); - setTimeout(() => { - server.close(); - server.listen(PORT, HOST); - }, 1000); - } -}); -``` - -(Note: All sockets in Node.js are set `SO_REUSEADDR`.) - -*Note*: The `server.listen()` method may be called multiple times. Each -subsequent call will *re-open* the server using the provided options. - ### server.listening -Creates a new server. The `connectionListener` argument is -automatically set as a listener for the [`'connection'`][] event. +Creates a new TCP or local server. -`options` is an object with the following defaults: +* `options` {Object} + * `allowHalfOpen` {boolean} Default to `false`. Indicates whether half-opened + TCP connections are allowed. + * `pauseOnConnect` {boolean} Default to `false`. Indicates whether the socket + should be paused on incoming connections. +* `connectionListener` {Function} Automatically set as a listener for the + [`'connection'`][] event -```js -{ - allowHalfOpen: false, - pauseOnConnect: false -} -``` +If `allowHalfOpen` is set to `true`, when the other end of the socket +sends a FIN packet, the server will only send a FIN packet back when +[`socket.end()`][] is explicitly called, until then the connection is +half-closed (non-readable but still writable). See [`'end'`][] event +and [RFC 1122][half-closed] for more information. -If `allowHalfOpen` is `true`, then the socket won't automatically send a FIN -packet when the other end of the socket sends a FIN packet. The socket becomes -non-readable, but still writable. You should call the [`end()`][] method explicitly. -See [`'end'`][] event for more information. +If `pauseOnConnect` is set to `true`, then the socket associated with each +incoming connection will be paused, and no data will be read from its handle. +This allows connections to be passed between processes without any data being +read by the original process. To begin reading data from a paused socket, call +[`socket.resume()`][]. -If `pauseOnConnect` is `true`, then the socket associated with each incoming -connection will be paused, and no data will be read from its handle. This allows -connections to be passed between processes without any data being read by the -original process. To begin reading data from a paused socket, call [`resume()`][]. +The server can be a TCP server or a local server, depending on what it +[`listen()`][`server.listen()`] to. -Here is an example of an echo server which listens for connections +Here is an example of an TCP echo server which listens for connections on port 8124: ```js @@ -947,22 +973,28 @@ Returns true if input is a version 6 IP address, otherwise returns false. [`'timeout'`]: #net_event_timeout [`child_process.fork()`]: child_process.html#child_process_child_process_fork_modulepath_args_options [`connect()`]: #net_socket_connect_options_connectlistener -[`destroy()`]: #net_socket_destroy_exception [`dns.lookup()`]: dns.html#dns_dns_lookup_hostname_options_callback [`dns.lookup()` hints]: dns.html#dns_supported_getaddrinfo_flags -[`end()`]: #net_socket_end_data_encoding +[`socket.end()`]: #net_socket_end_data_encoding [`EventEmitter`]: events.html#events_class_eventemitter [`net.createServer()`]: #net_net_createserver_options_connectionlistener +[`net.Server`]: #net_class_net_server [`net.Socket`]: #net_class_net_socket -[`pause()`]: #net_socket_pause -[`resume()`]: #net_socket_resume [`server.getConnections()`]: #net_server_getconnections_callback -[`server.listen(port, host, backlog, callback)`]: #net_server_listen_port_hostname_backlog_callback +[`server.listen()`]: #net_server_listen +[`server.listen(handle, backlog, callback)`]: #net_server_listen_handle_backlog_callback +[`server.listen(options, callback)`]: #net_server_listen_options_callback +[`server.listen(port, host, backlog, callback)`]: #net_server_listen_port_host_backlog_callback +[`server.listen(path, backlog, callback)`]: #net_server_listen_path_backlog_callback [`server.close()`]: #net_server_close_callback [`socket.connect(options, connectListener)`]: #net_socket_connect_options_connectlistener [`socket.connect`]: #net_socket_connect_options_connectlistener +[`socket.destroy()`]: #net_socket_destroy_exception [`socket.setTimeout()`]: #net_socket_settimeout_timeout_callback +[`socket.resume()`]: #net_socket_resume +[`socket.pause()`]: #net_socket_pause [`stream.setEncoding()`]: stream.html#stream_readable_setencoding_encoding +[half-closed]: https://tools.ietf.org/html/rfc1122#section-4.2.2.13 [Readable Stream]: stream.html#stream_class_stream_readable [unspecified IPv6 address]: https://en.wikipedia.org/wiki/IPv6_address#Unspecified_address [unspecified IPv4 address]: https://en.wikipedia.org/wiki/0.0.0.0 From d1ea3d2acd886dc74d380c9b2c61fa9b28c3b1da Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Thu, 2 Mar 2017 00:42:35 +0800 Subject: [PATCH 2/7] add stream-based --- doc/api/net.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/net.md b/doc/api/net.md index 194cdfc198c4f6..54e543a927dc36 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -2,7 +2,7 @@ > Stability: 2 - Stable -The `net` module provides an asynchronous network API for creating +The `net` module provides an asynchronous network API for creating stream-based servers ([`net.Server`][]) and clients ([`net.Socket`][]) that implement TCP or local communications (domain sockets on UNIX, named pipes on Windows). It can be accessed using: From 5896e3eb8a1d607425988cbd31744d1e0766c8bd Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Thu, 2 Mar 2017 01:17:56 +0800 Subject: [PATCH 3/7] socket(7), wrap links, arbitrary port --- doc/api/net.md | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/doc/api/net.md b/doc/api/net.md index 54e543a927dc36..9ca7bc46acba6a 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -82,7 +82,7 @@ var server = net.createServer((socket) => { throw err; }); -// grab a random port. +// grab an arbitrary unused port. server.listen(() => { console.log('opened server on', server.address()); }); @@ -136,10 +136,12 @@ what it listens to. Possible signatures: -* [`server.listen(handle[, backlog][, callback])`][`server.listen(handle, backlog, callback)`] -* [`server.listen(options[, callback])`][`server.listen(options, callback)`] -* [`server.listen(path[, backlog][, callback])`][`server.listen(path, backlog, callback)`] for local servers -* [`server.listen([port][, host][, backlog][, callback])`][`server.listen(port, host, backlog, callback)`] for TCP servers +* [`server.listen(handle[, backlog][, callback])`][`server.listen(handle)`] +* [`server.listen(options[, callback])`][`server.listen(options)`] +* [`server.listen(path[, backlog][, callback])`][`server.listen(path)`] + for local servers +* [`server.listen([port][, host][, backlog][, callback])`][`server.listen(port, host)`] + for TCP servers This function is asynchronous. When the server starts listening, the [`'listening'`][] event will be emitted. The last parameter `callback` @@ -153,7 +155,7 @@ on Linux. The default value of this parameter is 511 (not 512). Note: -* All [`net.Socket`][] are set to `SO_REUSEADDR`. +* All [`net.Socket`][] are set to `SO_REUSEADDR`(See [socket(7)][] for details). * The `server.listen()` method may be called multiple times. Each subsequent call will *re-open* the server using the provided options. @@ -207,9 +209,9 @@ added: v0.11.14 functions If `port` is specified, it behaves the same as -[`server.listen([port][, hostname][, backlog][, callback])`][`server.listen(port, host, backlog, callback)`]. +[`server.listen([port][, hostname][, backlog][, callback])`][`server.listen(port, host)`]. Otherwise, if `path` is specified, it behaves the same as -[`server.listen(path[, backlog][, callback])`][`server.listen(path, backlog, callback)`]. +[`server.listen(path[, backlog][, callback])`][`server.listen(path)`]. If none of them is specified, an error will be thrown. If `exclusive` is `false` (default), then cluster workers will use the same @@ -269,8 +271,7 @@ added: v0.1.90 Start a TCP server listening for connections on the given `port` and `host`. -If `port` is omitted or is 0, the operating system will assign a random -port, which can be retrieved by using `server.address().port` +If `port` is omitted or is 0, the operating system will assign an arbitrary unused port, which can be retrieved by using `server.address().port` after the [`'listening'`][] event has been emitted. If `host` is omitted, the server will accept connections on the @@ -982,10 +983,10 @@ Returns true if input is a version 6 IP address, otherwise returns false. [`net.Socket`]: #net_class_net_socket [`server.getConnections()`]: #net_server_getconnections_callback [`server.listen()`]: #net_server_listen -[`server.listen(handle, backlog, callback)`]: #net_server_listen_handle_backlog_callback -[`server.listen(options, callback)`]: #net_server_listen_options_callback -[`server.listen(port, host, backlog, callback)`]: #net_server_listen_port_host_backlog_callback -[`server.listen(path, backlog, callback)`]: #net_server_listen_path_backlog_callback +[`server.listen(handle)`]: #net_server_listen_handle_backlog_callback +[`server.listen(options)`]: #net_server_listen_options_callback +[`server.listen(port, host)`]: #net_server_listen_port_host_backlog_callback +[`server.listen(path)`]: #net_server_listen_path_backlog_callback [`server.close()`]: #net_server_close_callback [`socket.connect(options, connectListener)`]: #net_socket_connect_options_connectlistener [`socket.connect`]: #net_socket_connect_options_connectlistener @@ -996,5 +997,6 @@ Returns true if input is a version 6 IP address, otherwise returns false. [`stream.setEncoding()`]: stream.html#stream_readable_setencoding_encoding [half-closed]: https://tools.ietf.org/html/rfc1122#section-4.2.2.13 [Readable Stream]: stream.html#stream_class_stream_readable +[socket(7)]: http://man7.org/linux/man-pages/man7/socket.7.html [unspecified IPv6 address]: https://en.wikipedia.org/wiki/IPv6_address#Unspecified_address [unspecified IPv4 address]: https://en.wikipedia.org/wiki/0.0.0.0 From 5102522ce23afef0d74ca792a9ba1c9032ab5be4 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Thu, 2 Mar 2017 01:34:30 +0800 Subject: [PATCH 4/7] fix line wrap --- doc/api/net.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/api/net.md b/doc/api/net.md index 9ca7bc46acba6a..5fcdb81d3875a6 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -271,7 +271,8 @@ added: v0.1.90 Start a TCP server listening for connections on the given `port` and `host`. -If `port` is omitted or is 0, the operating system will assign an arbitrary unused port, which can be retrieved by using `server.address().port` +If `port` is omitted or is 0, the operating system will assign an arbitrary +unused port, which can be retrieved by using `server.address().port` after the [`'listening'`][] event has been emitted. If `host` is omitted, the server will accept connections on the From b78b5f3ed3326beeec521043d1a86825282483de Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Fri, 3 Mar 2017 11:13:40 +0800 Subject: [PATCH 5/7] fix link sort order --- doc/api/net.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/net.md b/doc/api/net.md index 5fcdb81d3875a6..87f76042cccdb7 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -977,7 +977,6 @@ Returns true if input is a version 6 IP address, otherwise returns false. [`connect()`]: #net_socket_connect_options_connectlistener [`dns.lookup()`]: dns.html#dns_dns_lookup_hostname_options_callback [`dns.lookup()` hints]: dns.html#dns_supported_getaddrinfo_flags -[`socket.end()`]: #net_socket_end_data_encoding [`EventEmitter`]: events.html#events_class_eventemitter [`net.createServer()`]: #net_net_createserver_options_connectionlistener [`net.Server`]: #net_class_net_server @@ -986,12 +985,13 @@ Returns true if input is a version 6 IP address, otherwise returns false. [`server.listen()`]: #net_server_listen [`server.listen(handle)`]: #net_server_listen_handle_backlog_callback [`server.listen(options)`]: #net_server_listen_options_callback -[`server.listen(port, host)`]: #net_server_listen_port_host_backlog_callback [`server.listen(path)`]: #net_server_listen_path_backlog_callback +[`server.listen(port, host)`]: #net_server_listen_port_host_backlog_callback [`server.close()`]: #net_server_close_callback [`socket.connect(options, connectListener)`]: #net_socket_connect_options_connectlistener [`socket.connect`]: #net_socket_connect_options_connectlistener [`socket.destroy()`]: #net_socket_destroy_exception +[`socket.end()`]: #net_socket_end_data_encoding [`socket.setTimeout()`]: #net_socket_settimeout_timeout_callback [`socket.resume()`]: #net_socket_resume [`socket.pause()`]: #net_socket_pause From fb61a637559fc79c26817f6b8ff2dba7a9a33b36 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Fri, 3 Mar 2017 11:24:22 +0800 Subject: [PATCH 6/7] address comments --- doc/api/net.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/doc/api/net.md b/doc/api/net.md index 87f76042cccdb7..84b82e18a8c157 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -3,7 +3,7 @@ > Stability: 2 - Stable The `net` module provides an asynchronous network API for creating stream-based -servers ([`net.Server`][]) and clients ([`net.Socket`][]) that implement TCP +servers ([`net.createServer()`][]) and clients ([`net.createConnection()`][]) that implement TCP or local communications (domain sockets on UNIX, named pipes on Windows). It can be accessed using: @@ -155,7 +155,8 @@ on Linux. The default value of this parameter is 511 (not 512). Note: -* All [`net.Socket`][] are set to `SO_REUSEADDR`(See [socket(7)][] for details). +* All [`net.Socket`][] are set to `SO_REUSEADDR` (See [socket(7)][] for + details). * The `server.listen()` method may be called multiple times. Each subsequent call will *re-open* the server using the provided options. @@ -405,14 +406,16 @@ See also: the return values of `socket.write()` added: v0.1.90 --> -Emitted when the other end of the socket sends a FIN packet. +Emitted when the other end of the socket sends a FIN packet, thus ending the +readable side of the socket. By default (`allowHalfOpen` is `false`) the socket will send a FIN packet back and destroy its file descriptor once it has written out its pending write queue. However, if `allowHalfOpen` is set to `true`, the socket will -not automatically [`end()`][`socket.end()`] its side, allowing the user to -write arbitrary amounts of data. The user must call [`end()`][`socket.end()`] -explicitly to close the connection. +not automatically [`end()`][`socket.end()`] its writable side, allowing the +user to write arbitrary amounts of data. The user must call +[`end()`][`socket.end()`] explicitly to close the connection (i.e. sending a +FIN packet back). ### Event: 'error'