UDT

互联网数据传输协议

基于UDP的数据传输协议(UDP-based Data Transfer Protocol,简称UDT)是一种互联网数据传输协议。UDT的主要目的是支持高速广域网上的海量数据传输,而互联网上的标准数据传输协议TCP在高带宽长距离网络上性能很差。 顾名思义,UDT建于UDP之上,并引入新的拥塞控制和数据可靠性控制机制。UDT是面向连接的双向的应用层协议。它同时支持可靠的数据流传输和部分可靠的数据报传输。 由于UDT完全在UDP上实现,它也可以应用在除了高速数据传输之外的其它应用领域,例如点到点技术(P2P),防火墙穿透,多媒体数据传输等等。

数据介绍
随着网络带宽时延积(BDP:the product of a data link's capacity (in bits per second) and its end-to-end delay)的增加,通常的TCP协议开始变的低效。这是因为它的AIMD(additive increase multiplicative decrease)算法完全减少了TCP拥塞窗口,但不能快速的恢复可用带宽。理论上的流量分析表明TCP在BDP增加到很高的时候比较容易受包损失攻击。
另外,继承自TCP拥塞控制的不公平的RTT也成为在分布式数据密集程式中的严重问题。拥有不同RTT的并发TCP流将不公平地分享带宽。尽管在小的BDP网络中使用通常的TCP实现来相对平等的共享带宽,但在拥有大量BDP的网络中,通常的基于TCP的程式就必须承受严重的不公平的问题。这个RTT基于的算法严重的限制了其在广域网分布式计算的效率,例如:internet上的网格计算。
一直到今天,对标准的TCP的提高一直都不能在高BDP环境中效率和公平性方面达到满意的程度(特别是基于RTT的问题)。例如:TCP的修改,RFC1423(高性能扩展),RFC2018(SACK)、RFC2582(New Reno)、RFC2883(D-SACK)、和RFC2988(RTO计算)都或多或少的提高了点效率,但最根本的AIMD算法没有解决。HS TCP(RFC 3649)通过根本上改变TCP拥塞控制算法来在高BDP网络中获得高带宽利用率,但公平性问题仍然存在。
考虑到上面的背景,需要一种在高BDP网络支持高性能数据传输的传输协议。我们推荐一个应用程式级别的传输协议,叫UDT或基于UDP的数据传输协议并有用拥塞控制算法。
本文描述两个正交的部分,UDP协议和UDT拥塞控制算法。一个应用层级别的协议,位于UDP之上,使用其他的拥塞算法,然而这些本文中描述的算法也能够在其他协议中实现,例如:TCP
一个协议的参考实现叫[UDT];周详的拥塞控制算法的性能分析在[GHG04]中能够找到。
2. 设计目标
UDT主要用在小数量的bulk源共享富裕带宽的情况下,最典型的例子就是建立在光纤广域网上的网格计算,一些研究所在这样的网络上运行他们的分布式的数据密集程式,例如,远程访问仪器、分布式数据挖掘和高分辨率的多媒体流。
UDT的主要目标是效率、公平、稳定。单个的或少量的UDT流应该利用任何高速连接提供的可用带宽,即使带宽变化的很剧烈。同时,任何并发的流必须公平地共享带宽,不依赖于不同的带宽瓶颈、起始时间、RTT。稳定性需要包发送速率应该一直会聚可用带宽很快,并且必须避免拥塞碰撞。
UDT并不是在瓶颈带宽相对较小的和大量多元短文档流的情况下用来取代TCP的。
UDT主要作为TCP的朋友,和TCP并存,UDT分配的带宽不应该超过根据MAX-MIN规则的最大最小公平共享原则。(备注,最大最小规则允许UDT在高BDP连接下分配TCP不能使用的可用带宽)。
3.1. 概述
UDT是双工的,每个UDT实体有两个部分:发送和接收。发送者根据流量控制和速率控制来发送(和重传)应用程式数据。接收者接收数据包和控制包,并根据接收到的包发送控制包。发送和接收程式共享同一个UDP端口来发送和接收。
接收者也负责触发和处理任何的控制事件,包括拥塞控制和可靠性控制和他们的相对机制,例如RTT估计、带宽估计、应答和重传。
UDT总是试着将应用层数据打包成固定的大小,除非数据不够这么大。和TCP相似的是,这个固定的包大小叫做MSS(最大包大小)。由于期望UDT用来传输大块数据流,我们假定只有很小的一部分不规则的大小的包在UDT session中。MSS能够通过应用程式来安装,MTU是其最优值(包括任何包头)。
UDT拥塞控制算法将速率控制和窗口(流量控制)合并起来,前者调整包的发送周期,后者限制最大的未被应答的包。在速率控制中使用的参数通过带宽估计技术来更新,他继承来自基于接收的包方法。同时,速率控制周期是估计RTT的常量,流控制参数依赖于对方的数据到达速度,另外接收端释放的缓冲区的大小。
3.2. 包结构
UDT有两种包:数据包和控制包。他们通过包头的第一位来区分(标志位)。假如是0,表示是数据包,1表示是控制包。
3.2.1. 数据包
数据包结构如下显示:
0 1 3 4
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
包序号
应用数据
包序号是UDT数据包头中唯一的内容。他是个无符号整数,使用标志位后的31位,UDT使用包基础的需要,例如,每个非重传的包都增加序号1。序号在到达最大值2^31-1的时候覆盖。紧跟在这些数据后面的是应用程式数据。
3.2.2. 控制包控制包结构如下:
0 1 3 4
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1
类型
保留
ACK序号
控制信息字段
有6种类型的控制包在UDT中,bit1-3表示这些信息。前32位在包头中必须存在。控制信息字段包括0(例如,他不存在)或多个32位无符号整数,这由包类型决定。
UDT使用应答子序号的方法。每个ACK/ACK2包有一个无符号的16位序号,他单独于数据包需要。他使用位16-31。应答需要从0到(2^16-1)。位16-31在其他控制包中没有定义。
类型
说明
控制信息
000
协议连接握手
1.32位 UDT版本
2.32位 内部顺序号
3.32位 MSS(字节
4.32位 最大流量窗口大小(字节)
001
保活
没有
010
应答,位16-31是应答序号
1.32位包序号,先前接收到的包序号
2.32位,RTT(微秒)
3.32位,RTT 变量或RTTVar (微秒)
4.32位,流量窗口大小(包的数量)
5.32位,连接容量估计(每秒包的数量)
011
Negative应答(NAK)
丢失信息的32位整数数组,见3.9节
100
保留
这种类型的控制信息保留作为拥塞警告使用,从接收到发送端。一个拥塞警告能被ECN或包延迟增加趋势的度量方法触发。
101
关闭
110
应答一个应答(ACK2)
16-31位,应答序号。
111
4-15的解释
保留将来使用
注意,对于数据和控制包来说,能够从UDP协议头中得到实际的包大小。包大小信息能被用来得到有效的数据负载和NAK包中的控制信息字段大小。
UDT在接收端使用4个定时器来触发不同的周期事件,包括速率控制、应答、丢失报告(negative应答)和重传/连接维护。
UDT中的定时器使用系统时间作为源。UDT接收端主动查询系统时间来检查一个定时器是否过期。对于某个定时器T来说,其拥有周期TP,将定变量t用来记录最近T被配置或复位的时间。假如T在系统时间t0(t= t0)被复位,那么任何t1(t1-t>=TP)是T过期的条件。
四个定时器是:RC定时器、ACK定时器、NAK定时器、EXP定时器。他们的周期分别是:RCTP、ATP、NTP、ETP。
RC定时器用来触发周期性的速率控制。ACK定时器用来触发周期性的有选择的应答(应答包)。RCTP和ATP是常量值,值为:RCTP=ATP=0.01秒。
NAK被用来触发negative应答(NAK包)。重传定时器被用来触发一个数据包的重传和维护连接状态。他们周期依赖于对于RTT的估计。ETP值也依赖于连续EXP时间溢出的次数。推荐的RTT初始值是0.1秒,而NTP和ETP的初始值是:NTP=3*RTT,ETP=3*RTT+ATP。
在每次bounded UDP接收操作(假如收到一个UDP包,一些额外的必须的数据处理时间)时查询系统时间来检查四个定时器是否已过期。推荐的周期粒度是微秒。UDP接收时间溢出值是实现的一个选择,这依赖于循环查询的负担和事件周期精确度之间的权衡。
速率控制事件更新包发送周期,UDT发送端使用STP来安排数据包的发送。假定一个在时间t0被发送,那么下一次包发送时间是(t0+ STP)。换句话说,假如前面的包发送花费了t’时间,发送端将等待(STP-t’)来发送下一个数据包(假如STP-t’ ,就无需等待了)。这个等待间隔需要一个高精确度的实现,推荐使用CPU时钟周期粒度。
3.4. 发送端算法
3.4.1. 数据结构和变量A. SND PKT历史窗口:一个循环数组记录每个数据包的开始时间
B. 发送端丢失链表:发送段丢失列表是个连接链表,用来存储被接收方NAK包中返回的丢失包序号。这些数字以增加的顺序存储。
3.4.2. 数据发送算法A. 假如发送端的丢失链表是非空的,重传第一个在list中的包,并删除该成员,到5。
B. 等待有应用程式数据需要发送
C. 假如未应答的包数量超过了两量窗口的大小,转到1。假如不是包装一个新的包并发送他。
D.假如当前包的序号是16n,n是个整数,转第2步。
E. 在SND PKT历史窗口中记录包的发送时间
F. 假如这是自上次发送速率降低之后的第一个包,等外SYN时间。
G.等外(STP – t)时间,t是第1到第4步之间的总时间,然后转到1。
3.5. 接收端算法
3.5.1. 数据结构和变量A. 接收端丢失链表:是个duple连接链表,元素的值包括:丢失数据包的序号、最近丢失包的反馈时间和包已被反馈的次数。值以包序号增序的方式存储。
B. 应答历史窗口:每个发送ACK的和时间一个循环数组;由于其循环的特性,意味着假如数组中没有更多空间的时候新的值将覆盖老的值。
C. RCV PKT历史窗口:一个用来记录每个包到达时间的循环数组
D.对包窗口:一个用来记录每个探测包对之间的时间间隔。
E. LRSN:一个用来记录最大接收数据包需要的变量。LRSN被初始化为初始序号减1。
3.5.2. 数据接收算法A. 查询系统时间来检查RC、ACK、NAK、或EXP定时器是否过期。假如任一定时器过期,处理事件(本节下面介绍)并复位过期的定时器。
B. 启动一个时间bounded UDP接收。假如每个包到,转1。
C. 配置exp-count为1,并更新ETP为:ETP=RTT+4*RTTVar + ATP。
D.假如任何的发送数据包已被应答,复位EXP时间变量。
E. 检查包头的标志位。假如是个控制包,根据类型处理他,然后转1。
F. 假如当前数据包的需要是16n+1,n是个整数,记录当前包和上个在对包窗口中数据包的时间间隔。
G.在PKT历史窗口中记录包到达时间
H. 假如当前数据包的序号大于LRSN+1,将任何在(但不包括)这两个值之间的序号放入接收丢失链表,并在一个NAK包中将这些序号发送给发送端。假如序号小于LRSN,从接收丢失链表中删除他。
I. 更新LRSN,转1。
3.5.3. RC定时器到通过速率控制算法来更新STP(见3.6节)。
过程如下:
A. 按照下面的原则查找接收端所接收到的任何包之前的序号:假如接收者丢失链表是空的,ACK号码是LRSN+1,否则是在接收丢失队列中的最小序号。
B. 假如应答号不大于曾被ACK2应答的最大应答号,或等于上次应答的应答号并且两次应答之间的时间间隔小于RTT+4*RTTVar,停止(不发送应答)。
C. 分配这个应答一个唯一增加的ACK序列号,推荐采用ACK序列号按步骤1增加,并且重叠在达到最大值之后。
D.根据下面的算法来计算包的抵达速度:使用PKT历史窗口中的值计算最近16个包抵达间隔(AI)中值。在这16个值中,删除那些大于AI*8或小于AI*8的包,假如最后剩余8个值,计算他们的平均值(AI’),包抵达速度是1/AI’(每秒包的数量),否则是0。
E. 根据3.7节中的内容为每端(W)计算流量窗口。然后计算有效的流量窗口大小为:最大(W,可用接收方缓冲大小),2。
F. 根据下面的算法来计算连接容量估计。假如流量控制快启动阶段(3.7)一直继续,返回0,否则计算最近16个对包间隔(PI),这些值在对包窗口中,那么连接容量就是1/PI(每秒包的数量)。
G.打包应答序列号,应答号,RTT,RTT 变量,有效的流量窗口大小并估计连接,将他们放入ACK包中,然后发送出去。
H. 记录ACK序列号,应答号和这个应答的开始时间,并放入历史窗口中。
3.5.4. 处理NAK定时器到时Ø 查找接受方的丢失链表,找到任何上次反馈时间是(k*(RTT+4*RTTVar) )前的包,k当前这个包的反馈次数加1,假如没有反馈丢失,停止。
Ø 压缩第一步中得到的序号(见3.9),然后在一个NAK包中发送他们到发送方。
Ø 假如不是停止流量控制快启动阶段。
3.5.5. 处理EXP定时器A. 假如发送端的丢失链表不是空的,停止
B. 将任何未应答的包放到发送端的丢失链表中
C. 假如(exp-count>16)并且自上次从对方接收到一个包以来的总时间超过3秒,或这个时间已超过3分钟了,这被认为是连接已断开,关闭UDT连接。
D.假如没有数据,也就没有应答,发送一个保活包给对端,否则将任何未应答包的序号放入发送丢失列表中。
E. 更新exp-count为:exp-count= exp-count+1
F. 更新ETP为:ETP=exp-count*(RTT+4*RTTVar)+ATP。
3.5.6. 收到应答包A. 更新最大的应答序号
B. 更新RTT和RTTVar为:RTT = rtt, RTTVar = rv;rtt和rv是ACK包中的RTT和RTTVar值。
C. 更新NTP和ETP为:NTP=RTT+4*RTTVar;ETP=exp-count*(RTT+4*RTTVar)+ATP
D. 更新连接容量估计:B=(B*7+b)/8,b是ACK包带的值。
E. 更新流量窗口大小为ACK中的值。
F. 发送ACK2包,并配置和ACK序号相同的应答号到对端
G. 复位EXP定时器
3.5.7. 当收到NAK包的时候A. 将任何NAK包中带的序号放入发送方的丢失列表中
B. 通过速率控制来更新STP(见3.6)
C. 复位EXP定时器
3.5.8. 当收到ACK2包Ø 在ACK历史窗口中根据接收到的ACK2序列号查找行营的ACK包。
Ø 更新曾被应答的最大应答号
Ø 根据ACK2的到达时间和ACK离开时间计算新的rtt值,并且更新RTT和RTTVar值为:
RTTVar = (RTTVar *3) +abs(rtt-RTT)/4
RTT = (RTT *7+rtt)/8
RTT和RTTVar的初始值是0.1秒和0.05秒。
Ø 更新NTP和ETP为:
NTP = RTT;
ETP = (exp-count +1)* RTT+ATP
3.5.9. 当收到保活包的时候什么也不做
3.5.10. 当收到连接握手和关闭包的时候见3.8节
3.6. 速度控制算法
3.6.1. 速率控制快启动STP被初始为最小的时间精度(1个CPU周期或1毫秒)。这是在快启动阶段,一般收到一个ACK包其携带的估计带宽大于0这个阶段就停止了。包的发送周期被配置为1/W,W是ACK携带的流量窗口的大小。
快启动阶段仅仅在开始一个UDT连接的时候发生,且不会在UDT连接的以后再出现。在快启动阶段之后,下面的算法就要工作了。
3.6.2. 当RC定时器时间到1. 假如在上一个RCTP时间内,没有收到一个ACK,停止
2. 计算在上个RCTP时间内的丢失率,计算方法是根据总共发送的包和NAK反馈中总共丢失包的数量。假如丢失率大于0.1%,停止。
3. 下个RCTP时间内发送包的增加数量如下计算:(inc)
If (B)
Else inc = max (10^(ceil(log10((B-C)*MSS*8)))*Beta/MSS,1/MSS)
B是连接容量估计,C是当前的发送速度。两个都计算为每秒多少个包。MSS是以字节计算的;Beta是值为0.0000015的常量。
4. 更新STP:STP=(STP*RCTP)/(STP*inc + RCTP)
5. 计算真正的数据发送周期(rsp),从SND PKT历史窗口中得到,假如(STP)配置STP为(0.5 * rsp)。
6. 假如(STP),配置STP为1.0。
3.6.3. 当收到NAK包时3.6.3.1. 数据结构和变量1. LSD:自上次速率降低后发送的最大序号
2. NumNAK:自上次LSD更新以后的NAK数量
3. AvgNAK:当最大序号大于LSD时两次事件之间的NAK移动的平均数。
4. DR:在1到AvgNAK之间的随机平均数。
3.6.3.2. 算法1. 假如NAK中最大的丢失序列号大于LSD:
增加STP为:STP=STP*(1+1/8)
更新AvgNAK为:AvgNAK = (AvgNAK *7 +NumNAK)/8
更新DR
复位 NumNAK = 0
记录LSD
2. 否则,增加NumNAK按照1个步骤增加;假如NumNAK % DR = 0;增加STP为:STP=STP*(1+1/8);记录LSD。
3.7. 流量控制算法
流量控制窗口大小(W)初始值是16。
3.7.1. 当ACK定时器到的时候1. 流量控制快启动:假如没有NAK产生或W没有到达或超过15个包,并且AS>0,流量窗口大小更新为应答包的总数量。
2. 否则,假如(AS>0),W更新为:(AS是包的到达速度)
W= ceil (W *0.875+AS* (RTT +ATP) *0.125)
3. 限制W到对方最大流量窗口大小。
3.8. 连接建立和关闭
一个UDT实体首先作为一个SERVER启动,当一个客户端需要连接的时候其发送握手包。客户端在从服务端接收到一个握手响应包或时间溢出之前,应该每隔一段时间发送一个握手包(时间间隔由响应时间和系统overhead来权衡)。
握手包有如下信息:
1. UDT版本:这个值是兼容的目的。当前的版本是2
2. 初始序号:这是发送这个UDT实体将来用于发送数据包的起始序号。他必须是个在1到(2^31-1)之间的随机值。另外,建议这个值在合理的时间历史窗口中不应该重复。
3. MSS:数据包的大小(通过IP有效负载来度量)
4. 最大的流量窗口大小:这是接收到握手信息的UDT实体允许的最大流量窗口大小,窗口大小通常限制为接收端的数据结构大小。
服务器接收到一个握手包之后,比较MSS值和他自己的值并配置他自己的值为较小的值。结果值也在握手响应中被发送到客户端,另外更有服务器的版本信息,初始序列号,最大流量窗口大小。
版本字段用来检查两端的兼容性。初始序列号和最大流量窗口大小用于初始化接收到这个握手包的UDT实体参数。
服务器在第一步完成以后就准备发送或接收数据。然而,只要从同一个客户端接收任何握手包,其应该发送响应包。
客户端一旦得到服务器的一个握手响应其就进入发送和接收数据状态。配置他自己的MSS为握手响应包中的值并初始化相应的参数为包中的值(序列号、最大流量窗口)。假如收到任何其他的握手信息,丢掉他。
假如其中的UDT实体要关闭,他将发送一个关闭信息到对端;对方收到这个信息以后将自己关闭。这个关闭信息通过UDP传输,仅仅发送一次,并不确保一定收到。假如消息没有收到,对方将根据时间溢出机制来关闭连接。
3.9. 丢失信息的压缩方案
NAK包中携带的丢失信息是个32-bit整数的数组。假如数组的中数字是个正常的序号(第1位是0),这意味着这个序号的包丢失了,假如第1位是1,意味着从这个号码开始(包括该号码)到下一个数组中的元素(包括这个元素值)之间的包(他的第1位必须是0)都丢失。
例如,下面的NAK中携带的信息:
0x00000002, 0x80000006, 0x0000000B, 0x0000000E
上面的信息表明序号为:2,6,7,8,9,10,11,14的包都丢了。
4. 效率和公平性
UDT能够充分利用当前有线网络的单独于连接容量的可用带宽 、RTT、后台共存流、给定的连接比特错误率。UDT在没有数据包丢失的情况下从0bits/s到90%带宽需要一个常量时间,这个时间是7.5秒。UDT并不适合无线网络。
UDT的确满足单瓶颈网络拓扑的最大-最小公平性。在多个瓶颈情况下,根据最大最小原则他能确保较小瓶颈连接或至少一半的平等共享(it guarantees that flows over smaller bottleneck links obtain at least half of their fair share according to max-min rule)。RTT对公平性都一点影响。
当和大块的TCP流共存的时候,TCP能占用比UDT更多的带宽,除了三种情况:
1. 网络BDP很大,TCP不能利用他们的公平共享带宽。这种情况下,UDT将占用TCP不能利用的带宽。
2. 连接容量是如此的小,从而导致UDT的带宽估计技术不能最有的工作;模拟显示这个极限连接容量大约是100kb/s。
3. 在使用FIFO队列作为网络路径的网络中,假如队列大小大于BDP,TCP的共享带宽随着队列大小的增加而降低。然而,抵达UDT的共享带宽是,队列大小通常超过实际路由器/交换机提供的数量。
当短(timewise)类似web的TCP流和小的并发UDT流共存的时候,UDT在TCP流上的效果很小。
更多的分析在[GHG03]。
5. 安全考虑UDT并没有使用特定的安全机制,相反,他依赖于应用程式提供的授权和底层提供的安全机制。
然而,由于UDP是无连接的,UDT实现应该检查任何达到的包是否是预期的来源。这是从socket的API连接概念中继承而来,其连接只是接收指定来源的数据。
6.UDT SOURCE CODE LINK
水下爆破队
(美国海军水下爆破队)UDT:Underwater Demolition team
UDT是美国海军在二战期间成立的精英部队,他们曾参与朝鲜战争越南战争。它们的主要功能是侦察和摧毁敌方的阻碍两栖登陆的海滩防御。他们还搜索阿波罗载人航天计划返回的宇航员。
UDT的侦察的海滩和海域只是其中会干扰登陆艇的岩石和暗礁。他们还用炸药摧毁敌人设置的水下障碍物。作为美国海军的游泳精英作战队员,他们受雇瘫痪保护敌人港口的电缆和网,在敌舰上安置炸弹,并为扫雷艇找到和标记地雷。他们还指挥河流侦查和外国的军事训练。
UDT的首创战斗游泳,闭路潜水,水下爆破,以及小型潜水艇(干式和湿式潜水)操作。他们是现今美国海军海豹突击队的先驱。
在1983年,经过额外的海豹突击队训练,UDT的被重新指定为海豹突击队或游泳配送车辆小组(SDVTs),至今已调任海豹配送车辆队伍。
通用变形工具
UDT:Rhinoceros(犀牛)软件里的一类工具总称,即Universal Deformation Tools,通用变形工具。主要有变形控制器、定位、流动、扭转、缩放、弯曲、锥状化/倾斜等。
UDT(user defined type) 用户自定义类型(Java)
全国各地天气预报查询

上海市

  • 市辖区
  • 云南省

  • 临沧市
  • 云南省

  • 丽江市
  • 云南省

  • 保山市
  • 云南省

  • 大理白族自治州
  • 云南省

  • 德宏傣族景颇族自治州
  • 云南省

  • 怒江傈僳族自治州
  • 云南省

  • 文山壮族苗族自治州
  • 云南省

  • 昆明市
  • 云南省

  • 昭通市
  • 云南省

  • 普洱市
  • 云南省

  • 曲靖市
  • 云南省

  • 楚雄彝族自治州
  • 云南省

  • 玉溪市
  • 云南省

  • 红河哈尼族彝族自治州
  • 云南省

  • 西双版纳傣族自治州
  • 云南省

  • 迪庆藏族自治州
  • 内蒙古自治区

  • 乌兰察布市
  • 内蒙古自治区

  • 乌海市
  • 内蒙古自治区

  • 兴安盟
  • 内蒙古自治区

  • 包头市
  • 内蒙古自治区

  • 呼伦贝尔市
  • 内蒙古自治区

  • 呼和浩特市
  • 内蒙古自治区

  • 巴彦淖尔市
  • 内蒙古自治区

  • 赤峰市
  • 内蒙古自治区

  • 通辽市
  • 内蒙古自治区

  • 鄂尔多斯市
  • 内蒙古自治区

  • 锡林郭勒盟
  • 内蒙古自治区

  • 阿拉善盟
  • 北京市

  • 市辖区
  • 吉林省

  • 吉林市
  • 吉林省

  • 四平市
  • 吉林省

  • 延边朝鲜族自治州
  • 吉林省

  • 松原市
  • 吉林省

  • 白城市
  • 吉林省

  • 白山市
  • 吉林省

  • 辽源市
  • 吉林省

  • 通化市
  • 吉林省

  • 长春市
  • 四川省

  • 乐山市
  • 四川省

  • 内江市
  • 四川省

  • 凉山彝族自治州
  • 四川省

  • 南充市
  • 四川省

  • 宜宾市
  • 四川省

  • 巴中市
  • 四川省

  • 广元市
  • 四川省

  • 广安市
  • 四川省

  • 德阳市
  • 四川省

  • 成都市
  • 四川省

  • 攀枝花市
  • 四川省

  • 泸州市
  • 四川省

  • 甘孜藏族自治州
  • 四川省

  • 眉山市
  • 四川省

  • 绵阳市
  • 四川省

  • 自贡市
  • 四川省

  • 资阳市
  • 四川省

  • 达州市
  • 四川省

  • 遂宁市
  • 四川省

  • 阿坝藏族羌族自治州
  • 四川省

  • 雅安市
  • 天津市

  • 市辖区
  • 宁夏回族自治区

  • 中卫市
  • 宁夏回族自治区

  • 吴忠市
  • 宁夏回族自治区

  • 固原市
  • 宁夏回族自治区

  • 石嘴山市
  • 宁夏回族自治区

  • 银川市
  • 安徽省

  • 亳州市
  • 安徽省

  • 六安市
  • 安徽省

  • 合肥市
  • 安徽省

  • 安庆市
  • 安徽省

  • 宣城市
  • 安徽省

  • 宿州市
  • 安徽省

  • 池州市
  • 安徽省

  • 淮北市
  • 安徽省

  • 淮南市
  • 安徽省

  • 滁州市
  • 安徽省

  • 芜湖市
  • 安徽省

  • 蚌埠市
  • 安徽省

  • 铜陵市
  • 安徽省

  • 阜阳市
  • 安徽省

  • 马鞍山市
  • 安徽省

  • 黄山市
  • 山东省

  • 东营市
  • 山东省

  • 临沂市
  • 山东省

  • 威海市
  • 山东省

  • 德州市
  • 山东省

  • 日照市
  • 山东省

  • 枣庄市
  • 山东省

  • 泰安市
  • 山东省

  • 济南市
  • 山东省

  • 济宁市
  • 山东省

  • 淄博市
  • 山东省

  • 滨州市
  • 山东省

  • 潍坊市
  • 山东省

  • 烟台市
  • 山东省

  • 聊城市
  • 山东省

  • 菏泽市
  • 山东省

  • 青岛市
  • 山西省

  • 临汾市
  • 山西省

  • 吕梁市
  • 山西省

  • 大同市
  • 山西省

  • 太原市
  • 山西省

  • 忻州市
  • 山西省

  • 晋中市
  • 山西省

  • 晋城市
  • 山西省

  • 朔州市
  • 山西省

  • 运城市
  • 山西省

  • 长治市
  • 山西省

  • 阳泉市
  • 广东省

  • 东莞市
  • 广东省

  • 中山市
  • 广东省

  • 云浮市
  • 广东省

  • 佛山市
  • 广东省

  • 广州市
  • 广东省

  • 惠州市
  • 广东省

  • 揭阳市
  • 广东省

  • 梅州市
  • 广东省

  • 汕头市
  • 广东省

  • 汕尾市
  • 广东省

  • 江门市
  • 广东省

  • 河源市
  • 广东省

  • 深圳市
  • 广东省

  • 清远市
  • 广东省

  • 湛江市
  • 广东省

  • 潮州市
  • 广东省

  • 珠海市
  • 广东省

  • 肇庆市
  • 广东省

  • 茂名市
  • 广东省

  • 阳江市
  • 广东省

  • 韶关市
  • 广西壮族自治区

  • 北海市
  • 广西壮族自治区

  • 南宁市
  • 广西壮族自治区

  • 崇左市
  • 广西壮族自治区

  • 来宾市
  • 广西壮族自治区

  • 柳州市
  • 广西壮族自治区

  • 桂林市
  • 广西壮族自治区

  • 梧州市
  • 广西壮族自治区

  • 河池市
  • 广西壮族自治区

  • 玉林市
  • 广西壮族自治区

  • 百色市
  • 广西壮族自治区

  • 贵港市
  • 广西壮族自治区

  • 贺州市
  • 广西壮族自治区

  • 钦州市
  • 广西壮族自治区

  • 防城港市
  • 新疆维吾尔自治区

  • 乌鲁木齐市
  • 新疆维吾尔自治区

  • 伊犁哈萨克自治州
  • 新疆维吾尔自治区

  • 克孜勒苏柯尔克孜自治州
  • 新疆维吾尔自治区

  • 克拉玛依市
  • 新疆维吾尔自治区

  • 博尔塔拉蒙古自治州
  • 新疆维吾尔自治区

  • 吐鲁番市
  • 新疆维吾尔自治区

  • 和田地区
  • 新疆维吾尔自治区

  • 哈密市
  • 新疆维吾尔自治区

  • 喀什地区
  • 新疆维吾尔自治区

  • 塔城地区
  • 新疆维吾尔自治区

  • 巴音郭楞蒙古自治州
  • 新疆维吾尔自治区

  • 昌吉回族自治州
  • 新疆维吾尔自治区

  • 自治区直辖县级行政区划
  • 新疆维吾尔自治区

  • 阿克苏地区
  • 新疆维吾尔自治区

  • 阿勒泰地区
  • 江苏省

  • 南京市
  • 江苏省

  • 南通市
  • 江苏省

  • 宿迁市
  • 江苏省

  • 常州市
  • 江苏省

  • 徐州市
  • 江苏省

  • 扬州市
  • 江苏省

  • 无锡市
  • 江苏省

  • 泰州市
  • 江苏省

  • 淮安市
  • 江苏省

  • 盐城市
  • 江苏省

  • 苏州市
  • 江苏省

  • 连云港市
  • 江苏省

  • 镇江市
  • 江西省

  • 上饶市
  • 江西省

  • 九江市
  • 江西省

  • 南昌市
  • 江西省

  • 吉安市
  • 江西省

  • 宜春市
  • 江西省

  • 抚州市
  • 江西省

  • 新余市
  • 江西省

  • 景德镇市
  • 江西省

  • 萍乡市
  • 江西省

  • 赣州市
  • 江西省

  • 鹰潭市
  • 河北省

  • 保定市
  • 河北省

  • 唐山市
  • 河北省

  • 廊坊市
  • 河北省

  • 张家口市
  • 河北省

  • 承德市
  • 河北省

  • 沧州市
  • 河北省

  • 石家庄市
  • 河北省

  • 秦皇岛市
  • 河北省

  • 衡水市
  • 河北省

  • 邢台市
  • 河北省

  • 邯郸市
  • 河南省

  • 三门峡市
  • 河南省

  • 信阳市
  • 河南省

  • 南阳市
  • 河南省

  • 周口市
  • 河南省

  • 商丘市
  • 河南省

  • 安阳市
  • 河南省

  • 平顶山市
  • 河南省

  • 开封市
  • 河南省

  • 新乡市
  • 河南省

  • 洛阳市
  • 河南省

  • 漯河市
  • 河南省

  • 濮阳市
  • 河南省

  • 焦作市
  • 河南省

  • 省直辖县级行政区划
  • 河南省

  • 许昌市
  • 河南省

  • 郑州市
  • 河南省

  • 驻马店市
  • 河南省

  • 鹤壁市
  • 浙江省

  • 丽水市
  • 浙江省

  • 台州市
  • 浙江省

  • 嘉兴市
  • 浙江省

  • 宁波市
  • 浙江省

  • 杭州市
  • 浙江省

  • 温州市
  • 浙江省

  • 湖州市
  • 浙江省

  • 绍兴市
  • 浙江省

  • 舟山市
  • 浙江省

  • 衢州市
  • 浙江省

  • 金华市
  • 海南省

  • 三亚市
  • 海南省

  • 三沙市
  • 海南省

  • 儋州市
  • 海南省

  • 海口市
  • 海南省

  • 省直辖县级行政区划
  • 湖北省

  • 十堰市
  • 湖北省

  • 咸宁市
  • 湖北省

  • 孝感市
  • 湖北省

  • 宜昌市
  • 湖北省

  • 恩施土家族苗族自治州
  • 湖北省

  • 武汉市
  • 湖北省

  • 省直辖县级行政区划
  • 湖北省

  • 荆州市
  • 湖北省

  • 荆门市
  • 湖北省

  • 襄阳市
  • 湖北省

  • 鄂州市
  • 湖北省

  • 随州市
  • 湖北省

  • 黄冈市
  • 湖北省

  • 黄石市
  • 湖南省

  • 娄底市
  • 湖南省

  • 岳阳市
  • 湖南省

  • 常德市
  • 湖南省

  • 张家界市
  • 湖南省

  • 怀化市
  • 湖南省

  • 株洲市
  • 湖南省

  • 永州市
  • 湖南省

  • 湘潭市
  • 湖南省

  • 湘西土家族苗族自治州
  • 湖南省

  • 益阳市
  • 湖南省

  • 衡阳市
  • 湖南省

  • 邵阳市
  • 湖南省

  • 郴州市
  • 湖南省

  • 长沙市
  • 甘肃省

  • 临夏回族自治州
  • 甘肃省

  • 兰州市
  • 甘肃省

  • 嘉峪关市
  • 甘肃省

  • 天水市
  • 甘肃省

  • 定西市
  • 甘肃省

  • 平凉市
  • 甘肃省

  • 庆阳市
  • 甘肃省

  • 张掖市
  • 甘肃省

  • 武威市
  • 甘肃省

  • 甘南藏族自治州
  • 甘肃省

  • 白银市
  • 甘肃省

  • 酒泉市
  • 甘肃省

  • 金昌市
  • 甘肃省

  • 陇南市
  • 福建省

  • 三明市
  • 福建省

  • 南平市
  • 福建省

  • 厦门市
  • 福建省

  • 宁德市
  • 福建省

  • 泉州市
  • 福建省

  • 漳州市
  • 福建省

  • 福州市
  • 福建省

  • 莆田市
  • 福建省

  • 龙岩市
  • 西藏自治区

  • 山南市
  • 西藏自治区

  • 拉萨市
  • 西藏自治区

  • 日喀则市
  • 西藏自治区

  • 昌都市
  • 西藏自治区

  • 林芝市
  • 西藏自治区

  • 那曲市
  • 西藏自治区

  • 阿里地区
  • 贵州省

  • 六盘水市
  • 贵州省

  • 安顺市
  • 贵州省

  • 毕节市
  • 贵州省

  • 贵阳市
  • 贵州省

  • 遵义市
  • 贵州省

  • 铜仁市
  • 贵州省

  • 黔东南苗族侗族自治州
  • 贵州省

  • 黔南布依族苗族自治州
  • 贵州省

  • 黔西南布依族苗族自治州
  • 辽宁省

  • 丹东市
  • 辽宁省

  • 大连市
  • 辽宁省

  • 抚顺市
  • 辽宁省

  • 朝阳市
  • 辽宁省

  • 本溪市
  • 辽宁省

  • 沈阳市
  • 辽宁省

  • 盘锦市
  • 辽宁省

  • 营口市
  • 辽宁省

  • 葫芦岛市
  • 辽宁省

  • 辽阳市
  • 辽宁省

  • 铁岭市
  • 辽宁省

  • 锦州市
  • 辽宁省

  • 阜新市
  • 辽宁省

  • 鞍山市
  • 重庆市

  • 重庆市

  • 市辖区
  • 陕西省

  • 咸阳市
  • 陕西省

  • 商洛市
  • 陕西省

  • 安康市
  • 陕西省

  • 宝鸡市
  • 陕西省

  • 延安市
  • 陕西省

  • 榆林市
  • 陕西省

  • 汉中市
  • 陕西省

  • 渭南市
  • 陕西省

  • 西安市
  • 陕西省

  • 铜川市
  • 青海省

  • 果洛藏族自治州
  • 青海省

  • 海东市
  • 青海省

  • 海北藏族自治州
  • 青海省

  • 海南藏族自治州
  • 青海省

  • 海西蒙古族藏族自治州
  • 青海省

  • 玉树藏族自治州
  • 青海省

  • 西宁市
  • 青海省

  • 黄南藏族自治州
  • 黑龙江省

  • 七台河市
  • 黑龙江省

  • 伊春市
  • 黑龙江省

  • 佳木斯市
  • 黑龙江省

  • 双鸭山市
  • 黑龙江省

  • 哈尔滨市
  • 黑龙江省

  • 大兴安岭地区
  • 黑龙江省

  • 大庆市
  • 黑龙江省

  • 牡丹江市
  • 黑龙江省

  • 绥化市
  • 黑龙江省

  • 鸡西市
  • 黑龙江省

  • 鹤岗市
  • 黑龙江省

  • 黑河市
  • 黑龙江省

  • 齐齐哈尔市