架设BT服务器和BitTorrent协议详解

如何架设一个BT服务器和 BitTorrent 协议详解 附原文
文章作者:Bram Cohen
信息来源:www.net130.com
翻译版本由孤波独立完成,孤波享有对该翻译版本解释权修改权
本文由ziyu5946转自iyfree.com,此处仅作学习收藏使用

BitTrrent(简称BT,比特洪流)是一个文件分发协议,它通过URL识别内容并且和网络无缝结合。它在HTTP平台上的优势在于,同时下在一个文件的下载者在下载的同时不断互相上传数据,使文件源可以在很有限的负载增加的情况下支持大量下载者同时下载。

一个BT式文件分发需要以下实体:

·一个普通网络服务器
·一个静态元信息文件
·一个BT Tracker
·一个“原始”下载者
·网络终端浏览者
·网络终端下载者

这里假设理想情况下一个文件有多个下载者。

架设一个BT服务器步骤如下:


1.开始运行Tracker(已运行的跳过这一步);
2.开始运行普通网络服务器端程序,如Apache,已运行的跳过这一步;
3.在网络服务器上将.torrent文件关联到Mimetype类型application/x-bittorrent(已关联的跳过这一步);
4.用要发布的完整文件和Tracker的URL创建一个元信息文件(.torrent文件);
5.将元信息文件放置在网络服务器上;
6.在网页上发布元信息文件(.torrent文件)链接;
7.原始下载者提供完整的文件(原本)。

通过BT下载步骤如下:

1.安装BT客户端程序(已安装的跳过这一步);
2.上网;
3.点击一个链到.torrent文件的链接;
4.选择本地存储路径,选定需要下载的文件(对有选择下载功能的BT客户端用户);
5.等待下载完成;
6.用户退出下载(之前下载者不停止上传)。

连接状况如下:

·网站正常提供静态文件连接,并且启动客户端上的BT程序;
·Tracker即时接收所有下载者信息,并且给每个下载者一份随机的peer列表。通过HTTP或HTTPS协议实现;
·下载者每隔一段时间连一次Tracher,告知自己的进度,并和那些已经直接连接上的peer进行数据的上传下载。这些连接遵循BitTorrent peer协议,通过TCP协议进行通信。
·原始下载者只上传不下载,他拥有整个文件,所以很必要向网络中传输完文件的所有部分。在一些人气很旺的下载中,原始下载者经常可以在较短的时间内退出上传,由其它已经下载到整个文件的下载者继续提供上传。

元信息文件和Tracker的回应信息都以一种简单高效可扩展的格式(Bencoding,B编码)传送。B编码过的信息就是以包含字符串和整型数据的字典和列表的嵌套(像在Python中一样),可扩展性是指可以通过减少字典忽略的关键值来添加新的特性。

B编码规则如下:

·字符串表示为十进制数的既定字符串长度加冒号再跟原字符串。
如4:spam就相当于'spam'。
·整型数据表示成前面加'i'后面加'e'中间是十进制数,如i3e就相当于3,i-3e就是-3。整型数据没有长度限制。i-0e无效,所有以'i0'开头的除了代表0的i0e,其它都无效。
·列表编码为一个'l'开头后面跟它所包含的项目(已经编码过)最后加一个'e',比如l4:spam4:eggse就等于<'spam', 'eggs'>。
·字典编码为一个'd'开头后面跟一个交替关键值(key)及其对应值的列表最后加一个'e'。
如:d3:cow3:moo4:spam4:eggse相当于{'cow': 'moo', 'spam': 'eggs'}
d4:spaml1:a1:bee相当于{'spam': <'a', 'b'>}
关键值必须是处理过的字符串(用原始字符串编码的,而且不是数字字母混合编码的)。

元信息文件就是B编码的有以下关键值的字典:

announce(声明)

Tracker的URL。

info(信息)

此关键值对应一个字典包含以下描述的关键值:

关键值name对应一个字符串,代表默认的下载文件或存成目录的名字。它是纯粹建议性的。

关键值piece length(块长)对应文件分割成的块的字节数。出于传输需要,文件被分割成大小相等的块,除了最后一块通常会小一些。块长一般来说是2的权值,大部分设块长为256K(2的18次幂)。

关键值pieces(块)对应一个字符串,此字符串长度是20的倍数。它可以再分成每20字节一段的多个字符串,分别对应块在索引中的SHA1校验码(hash)。

还有关键值length(长度)和files(文件),它们不能同时出现也不能都不出现。当length出现说明这个元信息文件只是单文件下载,否则说明是多文件的目录结构下载。

单文件情况下,length对应文件长度的字节数。

多文件情况被看作是把许多单文件按文件列表中的顺序连成一个大文件下载,而关键值files就对应文件列表,是一个字典的列表,其中每个字典又包含以下关键值:

length(长度) 文件长度的字节数。

path(路径) 一个包含字符串的列表,字符串就是子目录名,最后一项的字符串是文件名。
(一个长度为零的length表单是错误的。)

在单文件情况下,关键值name是文件名;多文件情况下,它就成了目录名。

Tracker质询是双向的。Tracker通过HTTP GET参数获得信息,然后返回一个B编码后的信息。尽管Tracker需要在服务器端执行,但它运行流畅像Apache的一个模块。

Tracker的GET请求有如下关键值:

info_hash

20字节长的SHA1验证码,来自B编码过的元信息文件中的info值下,是元信息文件的一个支链。这个值是自动转换的。

peer_id

一个20字节长的字符串,是每个用户开始下载时随机生成的ID。这个值也是是自动转换的。

ip

一个可选择的参数给出peer所在的IP(或DNS主机名),一般是和Tracker同机器的原始下载者得到后以便散发文件。

port

监听端口,官方默认的是从6881端口开始试,如果端口被占用则依次向后推一个端口找空闲端口,到6889端口为止。

uploaded

目前总上传量,编码为十进制ASCII码。

downloaded

目前总下载量,编码为十进制ASCII码。

left

未下载的字节数,编码为十进制ASCII码。这个数不是通过文件长度和已下载数算出来的,因为文件可能在被续传,还有一些已经下载的数据不能通过完整性检查必须重新下载。

event

这 是个选择性的关键值,选项有started,completed或stopped(或empty,等同于没有运行)。如果没有运行,这个声明会定期间隔一 定时间发出。开始下载时发出started值,完成下载时发出completed。当文件完整后再开始,没有completed发出,下载者中止下载时发 出stopped。

Tracker的回应也是B编码字典。如果Tracker回应中有关键值failure reason(失败原因),就会对应一个人可以读懂的字符串信息解释质询失败的原因,不需要其它关键值。否则,回应必须有两个关键值:interval (间隔)对应下载者定期发出请求的间隔秒数;peers,peer自选ID,IP地址或DNS主机名的字符串和端口号。记住peers不会完全按照计划的 间隔发送请求,假如他们发生一个事件或者想要更多的peers。

如果你想对元信息文件或者Tracker质询进行扩展,请与Bram Cohen进行协调,确保所有扩展都兼容。

BitTorrent peer协议通过TCP协议进行操作。它不用调节任何socket选项就可以流畅运行。

peer之间的连接是对称的。两个方向送出的信息要协调一致,数据可以流入任一方。

peer协议指一个peer从零开始下载,每得到元信息文件索引中所描述的一个块且验证码一致,就向所有peer声明已得到此块。

连接的两个终端有2个状态指标,被阻塞与否,被关注与否,被阻塞(choking)是表明在恢复通畅之前数据不再发出的通知。发生阻塞的原因和技术问题稍后会提到。

数 据传输发生在一方关注对方且对方没有阻塞的情况下。关注状态必须一致保持-如果一个没阻塞的peer没有别人需要的数据,别人对他就会失去关注,转而关注 那些正在阻塞的peer。完全执行这种条件需要非常慎重,但这样的确可以让下载者知道哪些peer在阻塞消失后可以马上开始下载。

连接会逐渐断开不感兴趣和阻塞的peer。

当数据传输时,下载者要备好多份请求排成队列,以获得较高的TCP传输效率(这叫“管运请求”)。另一方面,不能被写入TCP缓冲区的请求要被立即排入内存,而不是一个应用程序级的网络缓冲,一旦阻塞出现,这些请求全部丢弃。

peer连线协议包括一次握手跟着不断的大小一致且确定的信息流。握手的开始是字符十九(十进制),跟着是字符串'BitTorrentprotocol'。开头的字符是长度固定的,希望其它新协议也能这样以便区分。

此后所有送入协议的整数都编码为4字节大中止端。

在现有的应用中头部数据之后是8个全部预留为0的字节,若果你想通过改变这8个预留字节以扩展协议,请与Bram Cohen协调以保证所有扩展兼容。

然 后是来自元信息文件中B编码的info值中长20字节的SHA1验证码(和info_hash向Tracker声明的值相同,但这里是原始值那里是引 用)。如果双方的值不同,连接断开。一个例外是下载者想只用一个端口进行多个连接下载,它们会先从接入连接得到一个验证码,然后和列表里面的对照,有相同 的就答复。

验证码之后是20字节的peer id,它包含在Tracker回应的peer列表中,在向Tracker的请求中被报告。如果接受方peer id不符合发送方希望,连接断开。

握手完毕。之后是长度固定的交互信息流。零长度信息用来保持连接,被忽略。这种信息一般2分钟发出一次,但是在等待数据期间很容易超时。

所有非保持连接用信息开头的字节给出类型,可能值如下:

·0-阻塞
·1-通畅
·2-关注
·3-不关注
·4-有
·5-比特组
·6-请求
·7-块
·8-取消

“阻塞”、“通畅”、“关注”和“不关注”类信息没有荷载。

“比特组”类信息仅作为首信息发出。它负载一个比特组,下载者有索引的设为1,其它为0。开始下载时没有任何数据的下载者跳过“比特组”信息。首字节高位到低位对应索引0-7,依次类推,第二字节对应8-15,等等。尾部的剩余的比特位设为0。

“已有”类信息负载一个数,即刚下载并核对完验证码的索引数。

“请求”类信息包括包含一个索引,开始和长度。后两者是字节偏移。长度一般是2的权值除非被文件尾截断。现行一般是2的15次幂,并且关闭大于2的17次幂长度的连接。

“取 消”类信息负载和“请求”类信息有一样的负载。它通常在下载接近完成即“最后阶段”发出。当下载快要完成时,剩下几个块有都从同一个线程下载的趋向,这样 会很慢。为了确保剩余块下载迅速,一旦还没有决定剩余块的下载请求向谁发出,先向所有他正在从对方下载数据的连接者发送要求所有剩余块的请求。为避免低 效,每当一个块开始下载就向其他peer发出取消信息。

“块”类信息包含一个索引,开始和块。记住它和“请求”类信息是相关的。当传输速度很慢或“阻塞”“通畅”类信息高频率交替发出或两者同时发生,可能会载到一个不需要的块。

下载者下载块的顺序是随机的,这样适当防止下载者与其他Peers仅有相同的块子集或超集。

阻塞的发生有很多原因。TCP协议的信息拥挤控制在即时向多连接发送信息的过程中表现极差。同时,阻塞的存在使下载者们能够用以牙还牙式的算法来确保稳定的下载速率。

下面描述的阻塞算法是目前基础的配置。重要的是所有新算法不光要在包含全部扩展算法的网络中运行良好,也要在主要包含这个基础算法的网络中运行良好。

一 个优秀的阻塞算法有许多标准。它必须封锁一定同时上传的数量以获得良好的TCP表现,还要避免频繁的堵塞和通畅交替,即所谓“纤维化”。它应该用数据交换 报答给自己数据的peer。最后,它还应该偶尔尝试一下与未使用过的peer端连接,找出比现有连接好的连接,这叫做尝试性疏通。

现行的 阻塞算法避免纤维化的手段是每10秒转换被阻塞的名单。疏通4个自己关注且能从他们身上得到最高下载速率的peer,进行上传和数据交换。有较高上传速率 但是不被关注下载者的peer被疏通,一旦这些peer开始被关注,那些上传率最低的peer的就被阻塞。如果下载者有了完整的文件,他用自己的上传率而 不是下载率来决定疏通谁的连接。

在尝试性疏通中,任何一次中都有一个peer被疏通不管他的上传率如何(如果被关注,他会成为4个提供下载的peer之一)。被尝试性疏通的这种peer每30秒轮换一次。为了给它们一个上传整一个块的机会,新连接会以轮换中尝试性疏通次数的3倍开始连接。
附原文:
BitTorrent is a protocol for distributing files. It identifies content by URL and is designed to integrate seamlessly with the web. Its advantage over plain HTTP is that when multiple downloads of the same file happen concurrently, the downloaders upload to each other, making it possible for the file source to support very large numbers of downloaders with only a modest increase in its load.

A BitTorrent file distribution consists of these entities:

An ordinary web server
A static 'metainfo' file
A BitTorrent tracker
An 'original' downloader
The end user web browsers
The end user downloaders
There are ideally many end users for a single file.

To start serving, a host goes through the following steps:

Start running a tracker (or, more likely, have one running already).
Start running an ordinary web server, such as apache, or have one already.
Associate the extension .torrent with mimetype application/x-bittorrent on their web server (or have done so already).
Generate a metainfo (.torrent) file using the complete file to be served and the URL of the tracker.
Put the metainfo file on the web server.
Link to the metainfo (.torrent) file from some other web page.
Start a downloader which already has the complete file (the 'origin').
To start downloading, a user does the following:

Install BitTorrent (or have done so already).
Surf the web.
Click on a link to a .torrent file.
Select where to save the file locally, or select a partial download to resume.
Wait for download to complete.
Tell downloader to exit (it keeps uploading until this happens).
The connectivity is as follows:

The web site is serving up static files as normal, but kicking off the BitTorrent helper app on the clients.
The tracker is receiving information from all downloaders and giving them random lists of peers. This is done over HTTP or HTTPS.
Downloaders are periodically checking in with the tracker to keep it informed of their progress, and are uploading to and downloading from each other via direct connections. These connections use the BitTorrent peer protocol, which operates over TCP.
The origin is uploading but not downloading at all, since it has the entire file. The origin is necessary to get the entire file into the network. Often for popular downloads the origin can be taken down after a while since several downloads may have completed and been left running indefinitely.
Metainfo file and tracker responses are both sent in a simple, efficient, and extensible format called bencoding (pronounced 'bee encoding'). Bencoded messages are nested dictionaries and lists (as in Python), which can contain strings and integers. Extensibility is supported by ignoring unexpected dictionary keys, so additional optional ones can be added later
Bencoding is done as follows:

Strings are length-prefixed base ten followed by a colon and the string. For example 4:spam corresponds to 'spam'.
Integers are represented by an 'i' followed by the number in base 10 followed by an 'e'. For example i3e corresponds to 3 and i-3e corresponds to -3. Integers have no size limitation. i-0e is invalid. All encodings with a leading zero, such as i03e , are invalid, other than i0e , which of course corresponds to 0.
Lists are encoded as an 'l' followed by their elements (also bencoded) followed by an 'e'. For example l4:spam4:eggse corresponds to ['spam', 'eggs'].
Dictionaries are encoded as a 'd' followed by a list of alternating keys and their corresponding values followed by an 'e'. For example, d3:cow3:moo4:spam4:eggse corresponds to {'cow': 'moo', 'spam': 'eggs'} and d4:spaml1:a1:bee corresponds to {'spam': ['a', 'b']} . Keys must be strings and appear in sorted order (sorted as raw strings, not alphanumerics).
Metainfo files are bencoded dictionaries with the following keys:

announce

The URL of the tracker.

info

This maps to a dictionary, with keys described below.

The name key maps to a string which is the suggested name to save the file (or directory) as. It is purely advisory.

piece length maps to the number of bytes in each piece the file is split into. For the purposes of transfer, files are split into fixed-size pieces which are all the same length except for possibly the last one which may be truncated. Piece length is almost always a power of two, most commonly 2 18 = 256 K (BitTorrent prior to version 3.2 uses 2 20 = 1 M as default).

pieces maps to a string whose length is a multiple of 20. It is to be subdivided into strings of length 20, each of which is the SHA1 hash of the piece at the corresponding index.

There is also a key length or a key files , but not both or neither. If length is present then the download represents a single file, otherwise it represents a set of files which go in a directory structure.

In the single file case, length maps to the length of the file in bytes.

For the purposes of the other keys, the multi-file case is treated as only having a single file by concatenating the files in the order they appear in the files list. The files list is the value files maps to, and is a list of dictionaries containing the following keys:

length The length of the file, in bytes. path A list of strings corresponding to subdirectory names, the last of which is the actual file name (a zero length list is an error case).

In the single file case, the name key is the name of a file, in the muliple file case, it's the name of a directory.

Tracker queries are two way. The tracker receives information via HTTP GET parameters and returns a bencoded message. Note that although the current tracker implementation has its own web server, the tracker could run very nicely as, for example, an apache module.

Tracker GET requests have the following keys:

info_hash

The 20 byte sha1 hash of the bencoded form of the info value from the metainfo file. Note that this is a substring of the metainfo file. This value will almost certainly have to be escaped.

peer_id

A string of length 20 which this downloader uses as its id. Each downloader generates its own id at random at the start of a new download. This value will also almost certainly have to be escaped.

ip

An optional parameter giving the IP (or dns name) which this peer is at. Generally used for the origin if it's on the same machine as the tracker.

port

The port number this peer is listening on. Common behavior is for a downloader to try to listen on port 6881 and if that port is taken try 6882, then 6883, etc. and give up after 6889.

uploaded

The total amount uploaded so far, encoded in base ten ascii.

downloaded

The total amount downloaded so far, encoded in base ten ascii.

left

The number of bytes this peer still has to download, encoded in base ten ascii. Note that this can't be computed from downloaded and the file length since it might be a resume, and there's a chance that some of the downloaded data failed an integrity check and had to be re-downloaded.

event

This is an optional key which maps to started , completed , or stopped (or empty, which is the same as not being present). If not present, this is one of the announcements done at regular intervals. An announcement using started is sent when a download first begins, and one using completed is sent when the download is complete. No completed is sent if the file was complete when started. Downloaders send an announcement using 'stopped' when they cease downloading.

Tracker responses are bencoded dictionaries. If a tracker response has a key failure reason , then that maps to a human readable string which explains why the query failed, and no other keys are required. Otherwise, it must have two keys: interval , which maps to the number of seconds the downloader should wait between regular rerequests, and peers . peers maps to a list of dictionaries corresponding to peers, each of which contains the keys peer id , ip , and port , which map to the peer's self-selected ID, IP address or dns name as a string, and port number, respectively. Note that downloaders may rerequest on nonscheduled times if an event happens or they need more peers.

If you want to make any extensions to metainfo files or tracker queries, please coordinate with Bram Cohen to make sure that all extensions are done compatibly.

BitTorrent's peer protocol operates over TCP. It performs efficiently without setting any socket options.

Peer connections are symmetrical. Messages sent in both directions look the same, and data can flow in either direction.

The peer protocol refers to pieces of the file by index as described in the metainfo file, starting at zero. When a peer finishes downloading a piece and checks that the hash matches, it announces that it has that piece to all of its peers.

Connections contain two bits of state on either end: choked or not, and interested or not. Choking is a notification that no data will be sent until unchoking happens. The reasoning and common techniques behind choking are explained later in this document.

Data transfer takes place whenever one side is interested and the other side is not choking. Interest state must be kept up to date at all times - whenever a downloader doesn't have something they currently would ask a peer for in unchoked, they must express lack of interest, despite being choked. Implementing this properly is tricky, but makes it possible for downloaders to know which peers will start downloading immediately if unchoked.

Connections start out choked and not interested.

When data is being transferred, downloaders should keep several piece requests queued up at once in order to get good TCP performance (this is called 'pipelining'.) On the other side, requests which can't be written out to the TCP buffer immediately should be queued up in memory rather than kept in an application-level network buffer, so they can all be thrown out when a choke happens.

The peer wire protocol consists of a handshake followed by a never-ending stream of length-prefixed messages. The handshake starts with character ninteen (decimal) followed by the string 'BitTorrent protocol'. The leading character is a length prefix, put there in the hope that other new protocols may do the same and thus be trivially distinguishable from each other.

All later integers sent in the protocol are encoded as four bytes big-endian.

After the fixed headers come eight reserved bytes, which are all zero in all current implementations. If you wish to extend the protocol using these bytes, please coordinate with Bram Cohen to make sure all extensions are done compatibly.

Next comes the 20 byte sha1 hash of the bencoded form of the info value from the metainfo file. (This is the same value which is announced as info_hash to the tracker, only here it's raw instead of quoted here). If both sides don't send the same value, they sever the connection. The one possible exception is if a downloader wants to do multiple downloads over a single port, they may wait for incoming connections to give a download hash first, and respond with the same one if it's in their list.

After the download hash comes the 20-byte peer id which is reported in tracker requests and contained in peer lists in tracker responses. If the receiving side's peer id doesn't match the one the initiating side expects, it severs the connection.

That's it for handshaking, next comes an alternating stream of length prefixes and messages. Messages of length zero are keepalives, and ignored. Keepalives are generally sent once every two minutes, but note that timeouts can be done much more quickly when data is expected.

All non-keepalive messages start with a single byte which gives their type. The possible values are:

0 - choke
1 - unchoke
2 - interested
3 - not interested
4 - have
5 - bitfield
6 - request
7 - piece
8 - cancel
'choke', 'unchoke', 'interested', and 'not interested' have no payload.

'bitfield' is only ever sent as the first message. Its payload is a bitfield with each index that downloader has sent set to one and the rest set to zero. Downloaders which don't have anything yet may skip the 'bitfield' message. The first byte of the bitfield corresponds to indices 0 - 7 from high bit to low bit, respectively. The next one 8-15, etc. Spare bits at the end are set to zero.

The 'have' message's payload is a single number, the index which that downloader just completed and checked the hash of.

'request' messages contain an index, begin, and length. The last two are byte offsets. Length is generally a power of two unless it gets truncated by the end of the file. All current implementations use 2 15 , and close connections which request an amount greater than 2 17 .

'cancel' messages have the same payload as request messages. They are generally only sent towards the end of a download, during what's called 'endgame mode'. When a download is almost complete, there's a tendency for the last few pieces to all be downloaded off a single hosed modem line, taking a very long time. To make sure the last few pieces come in quickly, once requests for all pieces a given downloader doesn't have yet are currently pending, it sends requests for everything to everyone it's downloading from. To keep this from becoming horribly inefficient, it sends cancels to everyone else every time a piece arrives.

'piece' messages contain an index, begin, and piece. Note that they are correlated with request messages implicitly. It's possible for an unexpected piece to arrive if choke and unchoke messages are sent in quick succession and/or transfer is going very slowly.

Downloaders generally download pieces in random order, which does a reasonably good job of keeping them from having a strict subset or superset of the pieces of any of their peers.

Choking is done for several reasons. TCP congestion control behaves very poorly when sending over many connections at once. Also, choking lets each peer use a tit-for-tat-ish algorithm to ensure that they get a consistent download rate.

The choking algorithm described below is the currently deployed one. It is very important that all new algorithms work well both in a network consisting entirely of themselves and in a network consisting mostly of this one.

There are several criteria a good choking algorithm should meet. It should cap the number of simultaneous uploads for good TCP performance. It should avoid choking and unchoking quickly, known as 'fibrillation'. It should reciprocate to peers who let it download. Finally, it should try out unused connections once in a while to find out if they might be better than the currently used ones, known as optimistic unchoking.

The currently deployed choking algorithm avoids fibrillation by only changing who's choked once every ten seconds. It does reciprocation and number of uploads capping by unchoking the four peers which it has the best download rates from and are interested. Peers which have a better upload rate but aren't interested get unchoked and if they become interested the worst uploader gets choked. If a downloader has a complete file, it uses its upload rate rather than its download rate to decide who to unchoke.

For optimistic unchoking, at any one time there is a single peer which is unchoked regardless of it's upload rate (if interested, it counts as one of the four allowed downloaders.) Which peer is optimistically unchoked rotates every 30 seconds. To give them a decent chance of getting a complete piece to upload, new connections are three times as likely to start as the current optimistic unchoke as anywhere else in the rotation. 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值