Package Exports
- tftp
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (tftp) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
tftp
Streaming TFTP client and Server
WARNING
The implementation it's already done, you can GET and PUT files correctly. However, some optimizations must still be done, so for your safety don't use it in production or development, just for testing purposes. It will be ready when it reaches the version 0.1.0.
The server is currently not implemented.
Full-featured streaming TFTP client and server. It supports most of the RFCs:
- 1350 - The TFTP protocol ✓
- 2347 - Option extension ✓
- 2348 - Blocksize option ✓
- 2349 - Timeout Interval and Transfer Size Options ✓
- 2090 - Multicast option ✗
- 3617 - Uniform Resource Identifier (URI) ✓
- De facto (draft) - Windowsize option ✓
- De facto - Rollover option ✓
mailandnetasciitransfer modes ✗
Per se, the TFTP is a lock-step protocol built on top of UDP for transferring files between two machines. It was useful in the past but nowadays it's practically an obsolete legacy protocol useful in a very few scenarios. Without the extensions support, the RFC says that a file bigger than 32MB cannot be sent. This limit can be incremented to 91.74MB if both machines agree to use a block size of 1468 bytes, the MTU size before IP fragmentation in Ethernet networks. Also, the transfer speed is pretty slow due to the lock-step mechanism, one acknowledgement for each packet.
However, there are two de facto extensions that can boost the transfer speed and remove the size limit: the rollover and the window.
This module it's perfectly integrated with Node.js, providing an streaming interface for GETting and PUTing files very easily. No configuration is needed. By default the client tries to negotiate with the server the best possible configuration. If that's not possible it simply fallbacks to the original lock-step TFTP implementation.
It can be installed locally and use it programmatically, but it can be also installed globally and used directly from the console as a CLI utility.
Quick example
var tftp = require ("tftp");
var client = tftp.createClient ();
client.get ("remote-file", "local-file", function (error){
if (error) return console.error (error);
...
});
client.put ("local-file", "remote-file", function (error){
if (error) return console.error (error);
...
});Special thanks
Patrick Masotta (author of the Serva application and the internet draft about the windowsize option).
Documentation
Functions
Objects
Warning! UDP packet loss in Windows
Currently, in Windows there is a problem concerning the buffering of the received network packets (#6696). Basically, when the buffer is full, all the subsequent incoming packets are dropped, so they are never consumed by Node.js. This scenario can be reproduced by configuring a window bigger than 6 blocks with the default block size. So the advice is: do NOT increment the default window size (4) in the Windows platform until this bug is solved.
For the sake of simplicity the following examples omit the error handling. See the streams.js example or the source code of the get() and put() functions for more information.
GET remote → local
var get = client.createGetStream ("remote-file");
var write = fs.createWriteStream ("local-file");
get.pipe (write);PUT local → remote
var localFile = fs.createReadStream ("local-file");
var read = client.createPutStream ("remote-file", { size: totalSize });
read.pipe (put);npm install tftp -gThen you can access to the ntftp binary.
There are basically two ways to use it: with or without a shell.
Without a shell
Best for individual transfers.
$ ntftp get [options] <rfc3617_uri> [<local>]
$ ntftp put [options] [<local>] <rfc3617_uri>For example:
$ ntftp get tftp://localhost/remote-file
remote-file 42.2 MiB 32.6M/s 00:12 [###·····················] 13%$ ntftp put my/local-file tftp://localhost/remote-file
my/local-file 148.8 MiB 30.9M/s 00:07 [###########·············] 45%For more information type ntftp get|put -h.
With a shell
Best for multiple transfers, basically because the same server address and options are reused.
$ ntftp [options] <host>[:<port>]For example:
$ ntftp localhost
> get remote-file
remote-file 42.2 MiB 32.6M/s 00:12 [###·····················] 13%
> put my/local-file remote-file
my/local-file 148.8 MiB 30.9M/s 00:07 [###########·············] 45%For more information type ntftp -h and get|put -h.
module.createClient([options]) : Client
Returns a new Client instance.
var client = tftp.createClient ({
hostname: "10.10.10.10",
port: 1234
});Options:
hostname - String
The hostname. Default islocalhost.port - Number
The port number. Default is 69.blockSize - Number
The size of the DATA blocks. Valid range: [8, 65464]. Default is 1468, the MTU size before IP fragmentation in Ethernet networks.windowSize - Number
The size of each window. The window size means the number of blocks that can be sent/received without waiting an acknowledgement. Valid range: [1, 65535]. Default is 4.Comparison of transfer times:
Window size Improvement 1 -0% 2 -49% 3 -64% 4 -70% 5 -73% 6 -76% Take into account that with a bigger window more elements must be sorted (remember that UDP doesn't sort the incoming packets). This doesn't slow down the transfer very much but instead it requires more CPU. A window size of 4 is a good trade between speed and CPU usage.
Right now a window size of 6 is the maximum in Windows due to the packet loss. With a window size of 7 or greater a lot of timeouts and retransmissions begin to occur, so the recommendation is to use a window size of 4, the default value.
retries - Number
How many retries must be done before emitting an error. Default is 3.timeout - Number
Milliseconds to wait before a retry. Default is 3000.
Each of the following methods takes an options parameter. One option available is userExtensions, an object with properties to send along with a GET or PUT operation. For example:
var options = {
userExtensions: {
foo: "bar",
num: 2
}
}The server may ignore or not these extensions, this feature is server-dependent. Please note that the TFTP algorithm cannot be modified, these extensions must be related with something else. For example, you can implement a basic authentication; the client could send the extensions user and password and the server could validate the user and accept or deny the request. The extensions are transmitted in plain text.
The extensions timeout, tsize, blksize, windowsize and rollover are reserved and cannot be used.
Methods
- Client#createGetStream(remoteFile[, options]) : GetStream
- Client#createPutStream(remoteFile, options) : PutStream
- Client#get(remoteFile[, localFile][, options], callback) : undefined
- Client#put(localFile[, remoteFile][, options], callback) : undefined
Client#createGetStream(remoteFile[, options]) : GetStream
Returns a new GetStream instance.
Options:
- md5sum - String
MD5 sum for validating the integrity of the file. - sha1sum - String
SHA1 sum for validating the integrity of the file. - userExtensions - Object
Custom extensions to send with the request. More information.
var get = client.createGetStream ("file");Client#createPutStream(remoteFile, options) : PutStream
Returns a new PutStream instance.
Options:
- size - String
Total size of the file to upload. This option is required. - userExtensions - Object
Custom extensions to send with the request. More information.
var put = client.createPutStream ("file", { size: 1234 });Client#get(remoteFile[, localFile][, options], callback) : undefined
Downloads a file from the server. If the local filename is missing the filename of the remote file is used.
Options:
- md5sum - String
MD5 sum for validating the integrity of the file. - sha1sum - String
SHA1 sum for validating the integrity of the file. - userExtensions - Object
Custom extensions to send with the request. More information.
//tftp://<hostname>/file -> file
client.get ("file", function (error){
if (error) return console.error (error);
...
});Client#put(localFile[, remoteFile][, options], callback) : undefined
Uploads a file to the server. If the remote filename is missing the filename of the local file is used.
Options:
- userExtensions - Object
Custom extensions to send with the request. More information.
//file -> tftp://<hostname>/file
client.put ("file", function (error){
if (error) return console.error (error);
...
});The GetStream inherites from a Readable stream and the PutStream from a Writable stream. They have all the events and methods that can be found in the Readable and Writable streams, but they also define two more events and one more method.
Events
Methods
Emitted when abort() is called and the transfer has been aborted.
Emitted after the client negotiates the best possible configuration. When it is emitted the transfer still hasn't begun. It returns an object similar to this:
{
blockSize: 1468,
size: 105757295,
windowSize: 4,
userExtensions: null,
timeout: 3000,
localSocket: { address: "0.0.0.0", port: 58406 },
remoteSocket: { address: "127.0.0.1", port: 58407 },
file: "file",
retries: 3
}When the GetStream emits a stats event, the size property is not guaranteed to be a Number because the server may not implement all the RFCs. The size of the file is obtained during the negotiation but not all the servers are able to negotiate. In these cases the size is null.
The userExtensions property holds an object with the custom extensions sent by the server in response to the custom extensions sent in the request. Most of the TFTP servers with a GUI don't let you respond with custom extensions when in fact this is a feature explained in the RFCs, so unless the TFTP server allows you to respond with custom extensions, this property will be always null.
Aborts the current transfer and emits an abort event.


