Node.js缓冲器
纯JavaScript是Unicode友好的,但对二进制数据不是很好。当与TCP流或文件系统打交道时,有必要处理字节流。 Node提供缓冲器类,它提供实例来存储原始数据相似的一个整数数组,但对应于在V8堆外的原始存储器的分配。
Buffer类是一个全局类,可以在应用程序,导入缓冲模块进行访问。
创建缓冲区
Node缓冲器可以以各种方式来构造。
方法 1
以下是创建10个字节的汉缓冲的语法:
var buf = new Buffer(10);
方法 2
下面是用来从给定数组创建一个缓冲区的语法:
var buf = new Buffer([10, 20, 30, 40, 50]);
方法 3
下面是用来从给定的字符串和可选的编码类型创建缓冲区的语法:
var buf = new Buffer("Simply Easy Learning", "utf-8");
虽然“UTF8”是默认的编码,但你可以使用其它的编码: "ascii", "utf8", "utf16le", "ucs2", "base64" 或 "hex".
写到缓冲器
语法
以下被写入到一个节点缓冲器的方法的语法:
buf.write(string[, offset][, length][, encoding])
参数
下面是使用的参数的说明:
string - 这是要被写入的数据串缓冲区。
offset - 这是缓冲区开始的索引。默认值为0。
length - 这是要写入的字节的数目。默认是 buffer.length
encoding - 编码使用。 “UTF8”是默认的编码
返回值
这个方法返回写入的字节数。如果没有足够的空间在缓冲,以适应整个字符串,它将写该字符串的一部分。
示例
buf = new Buffer(256);
len = buf.write("Simply Easy Learning");
console.log("Octets written : "+ len);
当上述程序被执行时,它会产生以下结果:
Octets written : 20
从缓冲器读取
语法
下面是从节点缓冲器的数据的方法读取的语法:
buf.toString([encoding][, start][, end])
参数
下面是使用的参数的说明:
encoding - 编码使用。 “UTF8”是默认的编码
start - 开始读取的索引,默认为0。
end - 最终读数结束的索引,默认值是整个缓冲区。
返回值
此方法解码并返回来自使用指定的字符集编码的编码缓冲器的数据的字符串。
示例
buf = new Buffer(26);
for (var i = 0 ; i < 26 ; i++) {
buf[i] = i + 97;
}
console.log( buf.toString('ascii')); // outputs: abcdefghijklmnopqrstuvwxyz
console.log( buf.toString('ascii',0,5)); // outputs: abcde
console.log( buf.toString('utf8',0,5)); // outputs: abcde
console.log( buf.toString(undefined,0,5)); // encoding defaults to 'utf8', outputs abcde
当上述程序被执行时,它会产生以下结果:
abcdefghijklmnopqrstuvwxyz abcde abcde abcde
转换缓冲到JSON
语法
以下是转换节点缓存到JSON对象方法的语法:
buf.toJSON()
返回值
此方法返回缓冲区JSON-表示。
示例
var buf = new Buffer('Simply Easy Learning');
var json = buf.toJSON(buf);
console.log(json);
当上述程序被执行时,它会产生以下结果:
[ 83, 105, 109, 112, 108, 121, 32, 69, 97, 115, 121, 32, 76, 101, 97, 114, 110, 105, 110, 103 ]
接续缓冲器
语法
以下是连接Node缓存到单个节点缓存方法的语法:
Buffer.concat(list[, totalLength])
参数
下面是使用的参数的说明:
list -要连接缓冲区的数组对象列表
totalLength - 这是缓冲器连接在一起时的总长度
返回值
该方法返回一个缓冲区实例。
示例
var buffer1 = new Buffer('YiiBai ');
var buffer2 = new Buffer('Simply Easy Learning');
var buffer3 = Buffer.concat([buffer1,buffer2]);
console.log("buffer3 content: " + buffer3.toString());
当上述程序被执行时,它会产生以下结果:
buffer3 content: YiiBai Simply Easy Learning
比较缓冲器
语法
下面是比较两个Node缓冲器的方法的语法:
buf.compare(otherBuffer);
参数
下面是使用参数的说明:
otherBuffer - 这是将与被比较的其它缓冲 buf
返回值
返回一个数字,表示否到来之前或之后或和otherBuffer排序顺序一样。
示例
var buffer1 = new Buffer('ABC');
var buffer2 = new Buffer('ABCD');
var result = buffer1.compare(buffer2);
if(result < 0) {
console.log(buffer1 +" comes before " + buffer2);
}else if(result == 0){
console.log(buffer1 +" is same as " + buffer2);
}else {
console.log(buffer1 +" comes after " + buffer2);
}
当上述程序被执行时,它会产生以下结果:
ABC comes before ABCD
复制缓冲区
语法
以下是复制节点缓冲器的方法的语法:
buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd])
参数
下面是使用的参数的说明:
targetBuffer - 缓冲区对象的缓冲区将被复制。
targetStart - 数量,可选,默认:0
sourceStart - 数量,可选,默认:0
sourceEnd - 数量,可选,默认:buffer.length
返回值
没有返回值。拷贝数据从该缓冲器的一区域中,即使在目标内存区域与源重叠的目标缓冲器的区域。如果不确定targetStart,那么sourceStart参数默认为0,sourceEnd默认为buffer.length。
示例
var buffer1 = new Buffer('ABC');
//copy a buffer
var buffer2 = new Buffer(3);
buffer1.copy(buffer2);
console.log("buffer2 content: " + buffer2.toString());
当上述程序被执行时,它会产生以下结果:
buffer2 content: ABC
切片式缓冲器
语法
以下是获得一个节点缓冲器的子缓冲器的方法的语法:
buf.slice([start][, end])
参数
下面是使用的参数的说明:
start - 数量,可选,默认:0
end - 数量可选,默认:buffer.length
返回值
返回一个新的缓冲区,它引用相同的内存如old,并 start 切片(默认为0)和 end(默认为buffer.length)索引。负索引则从缓冲区末尾开始。
示例
var buffer1 = new Buffer('YiiBai');
//slicing a buffer
var buffer2 = buffer1.slice(0,9);
console.log("buffer2 content: " + buffer2.toString());
当上述程序被执行时,它会产生以下结果:
buffer2 content: Yiibai
缓冲区长度
语法
以下是得到以字节为单位的节点缓冲器的大小的方法的语法:
buf.length;
返回值
返回缓冲器的字节的大小。
示例
var buffer = new Buffer('YiiBai');
//length of the buffer
console.log("buffer length: " + buffer.length);
当上述程序被执行时,它会产生以下结果:
buffer length: 14
方法参考
以下是缓冲模块提供node.js参考,进一步的细节,可以参考官方文档。
| SN | 方法 & 描述 |
|---|---|
| 1 | new Buffer(size) 分配的大小为八位的一个新缓冲区。请注意,size不得超过kMaxLength。否则,引发RangeError将在这里抛出。 |
| 2 | new Buffer(buffer) 复制传递的缓冲区的数据到一个新的缓冲实例。 |
| 3 | new Buffer(str[, encoding]) 分配包含给定str是一个新的缓冲区。编码默认为 'utf8'. |
| 4 | buf.length 返回字节缓冲区的大小。注意,这并不一定是contents. length长度大小。存储器分配给缓冲对象的量。当缓冲器的内容被改变它不会改变。 |
| 5 | buf.write(string[, offset][, length][, encoding]) 写入字符串的使用给定的编码偏移缓冲区。 offset 默认是 0, 编码默认是 'utf8'. length 要写入的字节数。返回写入的字节数。 |
| 6 | buf.writeUIntLE(value, offset, byteLength[, noAssert]) 写入值到缓冲区指定的偏移量和byteLength。支持高达48位的精度。设置noAssert为true,以要跳过的值和偏移验证。默认为false。 |
| 7 | buf.writeUIntBE(value, offset, byteLength[, noAssert]) 写入值到缓冲区指定偏移量和byteLength。支持高达48位的精度。设置noAssert真要跳过的值和偏移验证。默认为false。 |
| 8 | buf.writeIntLE(value, offset, byteLength[, noAssert]) 写值到缓冲在指定偏移和byteLength. 支持高达48位的精度。设置noAssert真要跳过的值和偏移验证。默认为false。 |
| 9 | buf.writeIntBE(value, offset, byteLength[, noAssert]) 写入值到缓冲区指定的偏移量和byteLength。支持高达48位的精度。设置noAssert真要跳过的值和偏移验证。默认为false。 |
| 10 | buf.readUIntLE(offset, byteLength[, noAssert]) 广义版本是所有数值读取方法。支持高达48位的精度。设置noAssert为true时为跳过偏移验证。 这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 11 | buf.readUIntBE(offset, byteLength[, noAssert]) 广义版本是所有数值读取方法。支持高达48位的精度。设置noAssert为true时为跳过偏移验证。这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 12 | buf.readIntLE(offset, byteLength[, noAssert]) 广义版本是所有数值读取方法。支持高达48位的精度。设置noAssert为true时为跳过偏移验证。这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 13 | buf.readIntBE(offset, byteLength[, noAssert]) 广义版本是所有数值读取方法。支持高达48位的精度。设置noAssert为true时为跳过偏移验证。这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 14 | buf.toString([encoding][, start][, end]) 解码并返回使用指定的字符集编码编码缓冲数据的字符串。 |
| 15 | buf.toJSON() 返回缓冲区实例的JSON-表示。JSON.stringify字符串化一个缓冲区实例时,隐式调用这个函数。 |
| 16 | buf[index] 获取和设置字节索引。该值是指单个字节,所以合法范围为0x00和0xFF的十六进制或0和255之间。 |
| 17 | buf.equals(otherBuffer) 返回otherBuffer是否有相同的字节的布尔值。 |
| 18 | buf.compare(otherBuffer) 返回一个数字,表示是否到来之前或之后或在排序顺序和otherBuffer一样。 |
| 19 | buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd]) 从该缓冲器拷贝数据到一区域中,即使在目标内存区域与源重叠的目标缓冲器的区域。如果不确定targetStart和sourceStart参数默认为0,sourceEnd默认为buffer.length。 |
| 20 | buf.slice([start][, end]) 返回一个新的缓冲区,它引用相同的内存如old,但补偿并开始裁剪(默认为0)和结束(默认为buffer.length)索引。负索引从缓冲区末尾开始。 |
| 21 | buf.readUInt8(offset[, noAssert]) 从缓冲区读取一个无符号的8位整数指定的偏移量。设置noAssert为true时为跳过偏移验证。这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 22 | buf.readUInt16LE(offset[, noAssert]) 从缓冲区读取指定的偏移量与指定的endian格式的16位无符号整数。设置noAssert为true时为跳过偏移验证。这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 23 | buf.readUInt16BE(offset[, noAssert]) 从缓冲区读取指定偏移量与指定endian格式的16位无符号整数。设置noAssert为true时为跳过偏移验证。这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 24 | buf.readUInt32LE(offset[, noAssert]) 从缓冲区读取指定的偏移量与指定的endian格式的32位无符号整数。设置noAssert为true时为跳过偏移验证。这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 25 | buf.readUInt32BE(offset[, noAssert]) 从缓冲区读取指定偏移量使用指定的endian格式的32位无符号整数。设置noAssert为true时为跳过偏移验证。 这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 26 | buf.readInt8(offset[, noAssert]) 读取指定的偏移量从缓冲区中的有符号的8位整数。设置noAssert为true时为跳过偏移验证。这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 27 | buf.readInt16LE(offset[, noAssert]) 从缓冲区读取指定的偏移量使用指定endian格式有符号的16位整数。设置noAssert为true时为跳过偏移验证。这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 28 | buf.readInt16BE(offset[, noAssert]) 从缓冲区读取指定的偏移量使用指定endian格式有符号的16位整数。设置noAssert为true时为跳过偏移验证。 这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 29 | buf.readInt32LE(offset[, noAssert]) 从缓冲区读取指定的偏移量使用指定endian格式32位有符号整数。设置noAssert为true跳过偏移验证。这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 30 | buf.readInt32BE(offset[, noAssert]) 从缓冲区读取指定的偏移量使用指定endian格式32位有符号整数。设置noAssert为true时为跳过偏移验证。这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 31 | buf.readFloatLE(offset[, noAssert]) 从缓冲区读取指定的偏移量使用指定尾数格式的32位浮点。设置noAssert为true时为跳过偏移验证。这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 32 | buf.readFloatBE(offset[, noAssert]) 从缓冲区读取指定的偏移量使用指定尾数格式的32位浮点。设置noAssert为true时为跳过偏移验证。这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 33 | buf.readDoubleLE(offset[, noAssert]) 从缓冲区指定的偏移量读取一个64位的double,使用指定的endian格式。设置noAssert为true时为跳过偏移验证。这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 34 | buf.readDoubleBE(offset[, noAssert]) 读取一个64位的double从缓冲区指定的偏移量使用指定的endian格式。设置noAssert为true跳过偏移验证。这意味着,偏移可以是超出缓冲区的末尾。默认为false。 |
| 35 | buf.writeUInt8(value, offset[, noAssert]) 写入值到缓冲区指定的偏移量。注意,值必须是一个有效的无符号8位整数。设置noAssert为true时为跳过的值和偏移验证。这意味着值可能具体函数和偏移可能超出导致被丢弃的值长于缓冲区的末尾。这不应该被使用,除非是一定正确。默认为false。 |
| 36 | buf.writeUInt16LE(value, offset[, noAssert]) 写入值到缓冲区指定的偏移量使用指定endian格式。注意,值必须是一个有效的无符号的16位整数。设置noAssert为true时为要跳过的值和偏移验证。这意味着值可能具体函数和偏移可能超出导致被丢弃的值长于缓冲区的末尾。这不应该被使用,除非一定正确。默认为false。 |
| 37 | buf.writeUInt16BE(value, offset[, noAssert]) 写入值到缓冲区指定的偏移量使用指定endian格式。注意,值必须是一个有效的无符号的16位整数。设置noAssert为true时为要跳过的值和偏移验证。这意味着值可能具体函数和偏移可能超出导致被丢弃的值长于缓冲区的末尾。这不应该被使用,除非一定正确。默认为false。 |
| 38 | buf.writeUInt32LE(value, offset[, noAssert]) 写入值到缓冲区指定的偏移量使用指定endian格式。注意,值必须是一个有效的无符号的32位整数。设置noAssert为true时为要跳过的值和偏移验证。这意味着值可能太大的具体函数和偏移可能超出导致被丢弃的值长于缓冲区的末尾。这不应该被使用,除非一定正确。默认为false。 |
| 39 | buf.writeUInt32BE(value, offset[, noAssert]) 写入值到缓冲区指定的偏移量使用指定endian格式。注意,值必须是一个有效的无符号的32位整数。设置noAssert为true时为要跳过的值和偏移验证。这意味着值可能太大的具体函数和偏移可能超出导致被丢弃的值长于缓冲区的末尾。这不应该被使用,除非一定正确。默认为false。 |
| 40 | buf.writeInt8(value, offset[, noAssert]) 写入值到缓冲区指定的偏移量使用指定endian格式。注意,值必须是一个有效符号的8位整数。设置noAssert为true时为要跳过的值和偏移验证。这意味着值可能具体函数和偏移可能超出导致被丢弃的值的缓冲区的末尾。这不应该被使用,除非一定正确。默认为false。 |
| 41 | buf.writeInt16LE(value, offset[, noAssert]) 写入值到缓冲区指定的偏移量使用指定endian格式。注意,值必须是一个有效符号的16位整数。设置noAssert为true时为要跳过的值和偏移验证。这意味着值可能具体函数和偏移可能超出导致被丢弃的值长于缓冲区的末尾。这不应该被使用,除非一定正确。默认为false。 |
| 42 | buf.writeInt16BE(value, offset[, noAssert]) 写入值到缓冲区指定的偏移量使用指定endian格式。注意,值必须是一个有效符号的16位整数。设置noAssert为true时为要跳过的值和偏移验证。这意味着值可能具体函数和偏移可能超出导致被丢弃的值长于缓冲区的末尾。这不应该被使用,除非一定正确。默认为false。 |
| 43 | buf.writeInt32LE(value, offset[, noAssert]) 写入值到缓冲区指定的偏移量使用指定endian格式。注意,值必须是一个有效符号的32位整数。设置noAssert为true时为要跳过的值和偏移验证。这意味着值可能具体函数和偏移可能超出导致被丢弃的值长于缓冲区的末尾。这不应该被使用,除非你是一定的正确性。默认为false。 |
| 44 | buf.writeInt32BE(value, offset[, noAssert]) 写入值到缓冲区指定的偏移量使用指定endian格式。注意,值必须是一个有效符号的32位整数。设置noAssert为true时为要跳过的值和偏移验证。这意味着值可能具体函数和偏移可能超出导致被丢弃的值长于缓冲区的末尾。这不应该被使用,除非一定正确。默认为false。 |
| 45 | buf.writeFloatLE(value, offset[, noAssert]) 写入值到缓冲区指定的偏移量使用指定endian格式。注意,值必须是有效的32位浮点值。设置noAssert为true时为要跳过的值和偏移验证。这意味着值可能具体函数和偏移可能超出导致被丢弃的值长于缓冲区的末尾。这不应该被使用,除非一定正确。默认为false。 |
| 46 | buf.writeFloatBE(value, offset[, noAssert]) 写入值到缓冲区指定的偏移量使用指定endian格式。注意,值必须是有效的32位浮点。设置noAssert为true时为要跳过的值和偏移验证。这意味着值可能具体函数和偏移可能超出导致被丢弃的值长过了缓冲区的末尾。 这不应该被使用,除非是正确的。默认为false。 |
| 47 | buf.writeDoubleLE(value, offset[, noAssert]) 写入值到缓冲区指定偏移量使用指定的endian格式. 注意,值必须是有效的64位double。设置noAssert为true为要跳过的值和偏移验证。这意味着值可能太大的具体函数和偏移可能超出导致被丢弃的缓冲区末尾的值。这不应该被使用,除非是正确的。默认为false。 |
| 48 | buf.writeDoubleBE(value, offset[, noAssert]) 写入值到缓冲区指定的偏移量使用指定endian格式。注意,值必须是有效的64位double。设置noAssert为true为要跳过的值和偏移验证。这意味着值可能太大的具体函数和偏移可能超出导致被默默地丢弃的值的缓冲区的末尾。这不应该被使用,除非是一定正确。默认为false。 |
| 49 | buf.fill(value[, offset][, end]) 填充指定值的缓冲区。如果偏移量(默认为0)和结束(默认为buffer.length)不给它填满整个缓冲区。 |
类方法
| SN | 方法 & 描述 |
|---|---|
| 1 | Buffer.isEncoding(encoding) 返回true如果编码为有效编码参数,否则返回false |
| 2 | Buffer.isBuffer(obj) 测试如果obj是一个缓冲 |
| 3 | Buffer.byteLength(string[, encoding]) 给出了一个字符串的实际字节长度。编码默认为'utf8'。 ''. 这是不一样的字符串,prototype.length返回字符串中的字符的数目 |
| 4 | Buffer.concat(list[, totalLength]) 返回一个缓冲器是连接所有的缓冲器列表中的共同的结果 |
| 5 | Buffer.compare(buf1, buf2) 同buf1.compare(buf2)。有用于排序缓冲器数组 |
欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创优秀实例教程
转载请注明:文章转载自:易百教程 [http:/www.yiibai.com]
本文标题:Node.js缓冲器
本文地址:http://www.yiibai.com/nodejs/nodejs_buffers.html
Node.js缓冲器的更多相关文章
- node.js中Buffer缓冲器的使用
一.什么是Buffer Buffer缓冲器是用来存储输入和输出数据的一段内存.js语言没有二进制数据类型,在处理TCP和文件流的时候,就不是很方便了. 所以node.js提供了Buffer类来处理二进 ...
- node.js官方文档解析 02—buffer 缓冲器
Buffer 类的实例类似于整数数组,但 Buffer 的大小是固定的.且在 V8 堆外分配物理内存.Buffer 的大小在被创建时确定,且无法调整. Buffer 类在 Node.js 中是一个全局 ...
- Node.js快速入门
Node.js是什么? Node.js是建立在谷歌Chrome的JavaScript引擎(V8引擎)的Web应用程序框架. 它的最新版本是:v0.12.7(在编写本教程时的版本).Node.js在官方 ...
- node.js系列笔记之node.js初识《一》
node.js系列笔记之node.js初识<一> 一:环境说明 1.1 Linux系统CentOS 5.8 1.2 nodejs v0.10.15 1.3 nodejs源码下载地址 htt ...
- 理解Node.js安装及模块化
1.安装Node Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效. Node.j ...
- node.js入门学习笔记整理
(1)node Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. Node与javaScript的区别在于,javaScript的顶层对象是window,而no ...
- Node.js基本使用(超基础)
Node.js是什么 Node.js是一个能够在服务器端运行JavaScript的开放源代码.跨平台JavaScript运行环境 Node采用Google开发的V8引擎运行js代码,使用事件驱动.非阻 ...
- node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理
一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...
- 利用Node.js的Net模块实现一个命令行多人聊天室
1.net模块基本API 要使用Node.js的net模块实现一个命令行聊天室,就必须先了解NET模块的API使用.NET模块API分为两大类:Server和Socket类.工厂方法. Server类 ...
随机推荐
- UIButton图文上下对齐
- (void)centerImageAndTitle:(float)spacing { // get the size of the elements here for readability CG ...
- AlertDialog.Builder setCancelable用法
AlertDialog.Builder的setCancelable public AlertDialog.Builder setCancelable (boolean cancelable) Sinc ...
- 读TIJ -1 对象入门
<Thinking In Java·第 1 章对象入门> 第 1 章约20页,是对面向对象的程序设计(OOP)的一个综述. 依照其前言所述: "当中包含对"什么是对象& ...
- anzhaung
http://search.newhua.com/search_list.php?searchsid=1&searchname=Setu
- java面试32问
第一,谈谈final, finally, finalize的区别. 第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements ...
- iOS UIKit:viewController之定义(2)
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...
- CentOS 6.7编译安装MySQL 5.6
1.安装前准备 yum install make gcc gcc-c++ ncurses-devel perl bison-devel yum groupinstall "Developme ...
- Java 406
项目改名之后, 项目上传后,报错,406,可是项目本地是可以跑起来的, 联系管理员,管理员改了个/etc/httpd/conf/workers2.properties 里面,将本次的项目加入进去就OK ...
- Android开发手记(32) 使用摄像头拍照
在Android中,使用摄像头拍照一般有两种方法, 一种是调用系统自带的Camera,另一种是自己写一个摄像的界面. 我们要添加如下权限: <uses-permission android:na ...
- Visual C#实现Windows信使服务
现在有很多网络管理软件都具备网络上信息实时传送的功能,虽然有些网络通讯软件功能比较强大,有的软件不仅可以传送文本信息,还可以传送二进制文件等.但 它们都有一个无法克服的缺点,那就是分发比较困难,信息传 ...