
正文
关于tlv格式java代码的信息
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
linux服务器接收发送报文
它使用状态的“关联”(协会),两对SCTP用户协议之间的信息交换条款的定义。 SCTP也是一个面向连接的,但在概念上,SCTP“关联”更广泛的TCP连接相比,只有一个TCP连接的源地址和目的地址,SCTP提供了另一种方式为每个SCTP端点的运输提供了一组地址等端点传输地址= IP地址+端口号。
继承的TCP功能的基础上,SCTP提供了一些额外的功能:
1有序传输中的用户数据的多个“流”(流)
“流”是一系列的TCP中指的字节,而在SCTP是指某个系列的用户消息被发送到上层协议,这些消息的顺序与在流之内的其他消息。当建立关联,SCTP的用户的数据流的数目,可被提供给相关联的载体。此号码被商定的流的??数目与源端的用户相关联的消息。 SCTP为每个邮件中的链接发送给同行的流分配的序列号。在接收端,SCTP,以确保在一个给定的消息流的顺序被发送。另一方面,当工作流正在等待的下一个非顺序的用户消息的其他数据流的发送时,将继续下去。
2根据所发现的路径MTU(最大传输单元)的大小的用户数据切片
为了确保一致的SCTP报文发送到较低的路径MTU,SCTP用户消息分得一杯羹。传递给上部SCTP用户在接收端,切片重组。
3选择性确认(SACK)和拥塞控制
选择性确认数据包丢失,TCP序列号被返回给发送者已经成功地接收到的数据字节的序列号(不包括根据确认的字节数)的认可,并在SCTP反馈给发件人丢失,并要求序列号的消息重发。
SCTP使用的TCP拥塞控制技术,包括慢启动,拥塞避免和快速重传。因此,当一个共存和TCP应用程序时,SCTP的应用程序可以接收部分SCTP的网络资源。
4块(块)结合。
选择性地绑定到??SCTP包,即多个用户消息的消息发送到一个或多个数据结构的SCTP - “块”,SCTP储备应用程序消息传递框架边界。不同类型的块可以绑定到一个SCTP报文,但任何一个数据块之前,必须放在控制块。
5路径管理
SCTP路径管理功能主要是负责为目的地的运输提供了一个选择的目标地址的传输地址的远程地址,它是基于两个方面:SCTP用户的说明和合格的目的地。当其他流量控制不能提供可达性信息,定期扫描路径管理功能链接到SCTP报告在远程传输地址发生变化的可达性。 SCTP路径管理功能模块还负责建立链接,该报告的末端的本地地址,传输地址告诉SCTP用户的远程回报。
6,支持多归位
当SCTP传输的数据包的目的IP地址,如果IP地址是不可达的,SCTP消息重新路由到备用的IP地址。因此,在相关联,即使在两端的,可以容忍网络级别的错误的一端。
7对拒绝服务攻击(DoS)
DoS攻击的方法有很多种,最基本的DoS攻击就是利用合理的服务请求来占用过多的资源,从而使合法用户无法得到服务的响应。 SYN洪水攻击是一种拒绝服务攻击实例,是最好的方式了黑客攻击。针对SYN Flooding攻击的目标主机上,SCTP关联的初始化阶段,实施以“Cookie”的安全机制。
8支持多种传输模式
严格有序转移(如TCP)的有序转移(如每流)和无序传输(如UDP)的一部分。
2 SCTP报文结构
SCTP分组结构的数据分组,第一部分可以遵循由可变长度的数据块中的一个或多个。块类型 - 长度 - 值(TLV)格式。源端口,目的端口,校验的意义是与TCP类似的意义。确认标签保存价值的交流,第一次在SCTP握手初始标签。如果任何SCTP报文不包括联想这样的标签,当到达的时间将是在接收端丢弃。
包含的块类型,标记的转让处理,在每个块中的块长度,TLV。不同的块类型,可用于发送控制信息或数据。
发送序列号(TSN)和流序列号(SSN)是两个不同的序列号,TSN,以确保可靠性整个关联的SSN保证整个流的有序性,因此,在发送的数据的可靠性订货区分开来。
3 SCTP数据传输
4.1 SCTP四次握手的原则,抵制SYN洪水攻击
SCTP关联定义为:主机A的IP地址] + [主机的端口] + [IP地址的主机B] + [B主机端口。因此,相应的组的每个端部中的IP地址的任何一个可以是标记相关的,通过四向握手,作为相应的源/目的地地址和结束SCTP主机交换通信状态。
SYN洪水利用所固有的脆弱性,TCP / IP,TCP三次握手面向连接的SYN洪水的存在基础。 SYN Flooding攻击原理是:大量的恶意攻击者向服务器发送一个SYN包,服务器发出一个SYN + ACK数据包无法收到客户端的ACK包(第三次握手无法完成),服务器端将保持一个非常大名单的半连接,消耗大量的CPU时间和内存资源,也能保持此列表中的IP SYN + ACK的重试。服务器端将忙于处理攻击者伪造的TCP连接请求以及没有时间忽略正常的客户请求,从正常的客户的角度来看,服务器失去了响应。
在SCTP四次握手的INIT消息,接收端不保存任何状态信息或分配的任何资源,这样你就可以防止DoS攻击,如SYN洪水。 INIT-ACK消息发送,使用了一种机制 - “状态曲奇”的cookie的发送者建立自己的国家所需的全部信息。
SCTP产生一个Cookie状态过程如下:
1。收到的INIT发出的INIT ACK数据块的信息来创建一个关联的TCB(传输控制块)。
在TCB中,生存在协议参数设置为“有效的Cookie时间,创建日期设置为当前日期。
3根据TCB收集重建的TCB所需的最小的子集的信息,这个子集和密钥来产生一个MAC(消息认证码)。
用最小的子集的信息和MAC产生状态Cookie。
5。在发送的INIT ACK(含状态cookie参数),发送者必须删除TCB,以及任何相关的新的关联的本地资源。
INIT和INIT ACK必须包含建立初始状态所需的参数:一组IP地址,以确保可靠的传输的初始TSN,每一个收到的SCTP包中必须包含初始标签,每一端的请求发出的数据流的数量并在每一端可以支持接收的数据流的数量。交换这些消息,INIT COOKIE-ECHO消息的发送者被送回的状态Cookie。接收端在接收COOKIE-ECHO饼干的状态,完成重建自己的国家和回送COOKIE-ACK确认该协会已成立。 COOKIE-ECHO和COOKIE-ACK的用户数据信息可以绑定到每个包。
因此,使用上述的以这样的方式,即使接收INIT消息,接收终端,也没有任何的资源消耗:它既不分配任何系统资源,并且不保存的新的关联的状态,它是只对口援建的状态状态的Cookie作为一个参数,它包含每一个回送的INIT-ACK消息,并最终状态cookie COOKIE-ECHO消息发送回。
2.2 SCTP的数据交换
正常的两个SCTP主机之间的数据交换。 SCTP主机发送SACK块,用来确认每一个收到的SCTP报文。 SACK的完全描述的接收侧的状态,可以使发送侧决定的重发,因此,在根据对SACK。 SCTP支持TCP快速重传和超时重传算法类似。
SCTP和TCP数据包丢失,使用不同的机制:TCP序列号空缺已被填补缺口,直到收到,发送丢失的数据包数据的序列号是高于之前。但是,SCTP即使收到订单的序列号空缺,并会不断发回数据。
3.3 SCTP关联关闭
面向连接的传输协议,SCTP还可以使用与TCP的三次握手关闭相关,但有一点不同:在“关联关闭”的过程中保持连接打开一个TCP终端,新的数据来自对等体,但不支持TCP SCTP这个“半封闭”状态。 1日发布由主机A“OFF”(关闭)块终止与主机B,主机A就会进入“SHUTDOWN-PENDING”状态,相应的动作是:不再接受上层应用的数据,并且只发送队列中剩余的数据,进入“SHUTDOWN-SENT”状态。
一旦主机B接收到“OFF”挡,进入“SHUTDOWN-RECEIVED”状态,与主机A,不再接受上层应用的数据,只发送队列中剩余的数据。
主机A再发送“关闭”块,剩余的数据已经达到主机B发出的通知,并重申,该协会正在关闭。
当第二个获得“关闭”块,主机B发送确认关闭“块。
随后的主机发送“关闭”结束“块完成关闭的关联。
4结论
SCTP是开发用于传输信令流量,但它有一定的优势,先进的TCP协议机制,如选择性确认,快速重传,无序提交,因此,它也满足高性能传输的需求,这将赋予它更广泛的应用的要求。目前,有各种各样的操作系统都支持SCTP,如Linux,AIX和Solaris上,Windows中,FressBSD。不同的协议之间的互操作性测试取得成功,揭示了SCTP正走向商业产品的道路。
IEFT致力于SCTP进一步的,以使其更好地满足下一代应用的需求,如支持IPv6地址,解决对端的IPv6站点本地和链路本地地址不连接的问题,以及在现有的关联动态添加或删除IP地址,而无需重新启动关联。
此外,在第三代移动通信,SCTP信令承载层的选择之一,它的应用及其性能评价是还待研究。
参考文献:
相关问答
Q1: ProtocolBuffer浅析
ProtocolBuffer是google 定义的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。ProtocolBuffer类似于xml、json,不过它更小、更快、也更简单。
目前使用最广泛的数据传输协议为JSON,JSON是一种轻量级的数据交换格式而且层次和结构比较简单和清晰,这里主要对比一下Protocol Buffer和JSON的对比,给出优势和劣势:
优势
劣势
实际数据对比
Protocol Buffer的使用流程总体可以分为三步,如下图所示:
google推荐在Android项目中使用lite版,lite版本生成的java文件更加轻量,其配置如下:
首先创建一个.proto文件,并且在文件中声明如下内容:
在整个proto文件中数据类型分为基本类型和结构类型,其中结构类型主要为:
下面分别介绍一下不同结构的作用及规定:
message表示一个结构,类似于java中类,一个proto文件中可以声明多个message结构:
message可以引用不同proto文件中的message,只要在proto文件中的最上面声明import即可,如下所示:
enum使用很简单,直接在message中声明enum结构体并且将属性声明为对应的enum即可:
在proto3中,enum第一个值必须为0,主要是为了和基础类型的默认值保持一致
map是proto3新加的,使用也很简单:
如下
repeated修饰的属性类似于jsonArray,也类似于java中的List,该修饰符在格式正确的消息中可以重复任意次(包括0次)
日常开发过程中,由于需求的变更,往往需要增加字段,这就涉及到字段的扩充,字段扩充需要达到一个目的: 兼容
所以Protocol Buffer在字段扩充中定义了如下规则:
只要记住上述规则,就能完成字段扩充且老版本也能兼容
Protocol Buffer 更快更小的主要原因如下:
上面这个例子中,在序列化时,"name" 、"count"的key值不会参与,由编号1、2代替,这样在反序列化的时候直接通过编号找到对应的key就可以。需要注意的是编号一旦确定就不可以更改,服务端和客户端通过proto通信的时候需要提前定义号数据格式。
其中Length不一定有,依据Tag确定,例如int类型的数据就只有Tag-Value,string类型的数据就必须是Tag-Length-Value。
Protocol Buffer定义了如下的数据类型,其中部分数据类型已经不再使用:
上面已经介绍了Protocol Buffer的数据结构及Tag的类型,但是Tag块并不是只表示数据类型,其中数据编号也在Tag块中,Tag的生成规则如下:
其中Tag块的后3位表示数据类型,其他位表示数据编号
Java中整数类型的长度都是确定的,如int类型的长度为4个字节,可表示的整数范围为-2 31——2 31-1,但是实际开发中用到的数字均比较小,会造成字节浪费,可变长度编码就能很好的解决这个问题,可变长度编码规则如下:
举个例子:
其中第一个字节由于最高位为1,则后面的字节也是前面的数据的一部分,第二个字节最高位为0,则表示数据计算终止,由于Protocol Buffer是低位在前,整体的转换过程如下:
10000001 00000011 —— 00000110000001 表示的10进制数为:2^0 + 2^7 + 2^8 = 385 通过上面的例子可以知道一个字节表示的数的范围0-128,上面介绍的Tag生成算法中由于后3位表示数据类型,所以Tag中1-15编号只占用1个字节,所以确保编号中1-15为常用的,减少数据大小。
可变长度编码唯一的缺点就是当数很大的时候int32需要占用5个字节,但是从统计学角度来说,一般不会有这么大的数.
上面介绍了Protocol Buffer的原理,现在通过实例来展示分析过程,我们定义的proto文件如下:
其序列化后的字节数据如下:
前面介绍过Protocol Buffer的 数据结构为TLV,其中L不是必须的,根据T的类型来确定 先看下第一个字节:
这里字节最高位为0,所以该Tag就用这一个字节表示,其中后3位表示类型,前面表示字段编号,所以:
这里字节最高位为0,所以该Tag就用这一个字节表示,其中后3位表示类型,前面表示字段编号,所以: file_num = 0001 = 1 type = 010 = 2 上面介绍过type=2,则后面有Length,按照可变长度编码规则,知道表示长度的字节为:
所以Length=4,则value的长度是4个字节,直接取出后面4个字节:
这4个字节对应的就是test 再看下一组:
由上面的Tag知道: file_num=2 type=0 前面介绍过type=0,后面没有Length,直接就是value,
value=1,通过上面的解析可以知道
上面介绍了Protocol Buffer的原理,解释了为什么Protocol Buffer更快,更小,这里再总结一下:
参考资料:
proto3官网指南:
protobuf-gradle-plugin:
博客:
Q2: 在java中怎么将一组数据从客户端发送到服务器端???
通过反射!
下面是一个服务器与客户端信息交互的例子:
反射API介绍
4.Java Socket编程 TCP 协议编程
1) TCP工作模型: 先找
堂(主机/IP), 到食堂以后找窗口
(Socket/套接字 端口号), 服务员等待连接,客户向服务员发起连接
连接以后, 一个窗口可以为每个客户安排一个服务员(线程)提供服务,
每个服务过程可以双向交流通讯(流), 通讯完成后要关闭连接.
5. TCP 服务端编程(食堂)(java.io.*,java.net.*,java.lang.*)
1) 创建ServerSocket实例绑定一个服务端口(Socket/套接字 端口号)
2) 开始ServerSocket实例 的监听, 等待客户端的连接
3) 如果有客户连接进来, 就获得了客户的套接字(Socket)实例
客户的套接字(Socket)实例中包括与客户端建立的连接流
4) 为这个客户(Socket) 创建一个服务线程, 提供服务(run方法)
5) 继续等待下一个连接, 返回到2)
6) 服务线程 完成通讯服务过程
7) 端口号: 0~65535, 1K以下留给系统使用
6. TCP 客户端编程
1) 创建Socket 实例, 连接到服务器端, 成功创建s就表示连接到了
服务器
Socket s = new Socket("host", port)
2) 客户端 Socket 与服务器端 Socket 对应, 都包含输入, 输出流
客户端的s.getInputStream() 连接于服务器s.getOutputStream()
客户端的s.getOutputStream()连接于服务器s.getInputStream()
3) 使用线程处理 网络流
7. Java 反射
1) 反射是Java自我管理(类, 对象)的机制
2) * 可以通过反射机制发现对象的类型 发现类型的方法/属性/构造器
3) * Java 反射 可以创建对象 并 访问任意对象方法和属性等
4) Class 加载
类加载到内存: java 将磁盘类文件加载到内存中,为一个对象(实例)
这个对象是Class的实例, 也就是 这些对象都是Class实例
5)Class 实例代表Java中类型, 基本类型的类型: int.class, long.class
类类型 Class 实例获得如下:
Class cls = String.class;
Class cls = Class.forName("java.lang.String");
Class cls = "abc".getClass();
以上方法获得cls 是同一个对象, 就是String 类内存加载的结果
package javase2.day06.ftp;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import java.util.Scanner;/** * ftp 客户端 可以使用命令 ls pwd get */public class FtpClient { public static void main(String[] args) throws IOException{ FtpClient client = new FtpClient(); client.open(); } public void open() throws IOException{ Socket s = new Socket("localhost", 9000); InputStream in = s.getInputStream(); OutputStream out = s.getOutputStream(); //处理客户端对服务器的请求 new RequestProcess(out).start(); //处理服务器的反馈信息 new ResponseProcess(in).start(); }//处理客户端对服务器的请求 class RequestProcess extends Thread{ OutputStream out; public RequestProcess(OutputStream out) { this.out = out; } public void run() { try{ Scanner sc = new Scanner(System.in); while(true){ String s = sc.nextLine(); IOUtils.println(out, s); if(s.equals("bye")){ System.exit(0); } } }catch(IOException e){ e.printStackTrace(); } } } class ResponseProcess extends Thread{ InputStream in; public ResponseProcess(InputStream in) { this.in = in; } public void run() { try{ while(true){ String header = IOUtils.readLine(in); if(header.startsWith("text,")){ show(header,in); }else if(header.startsWith("file,")){ save(header, in); } } }catch(IOException e){ e.printStackTrace(); } } } public void show(String header, InputStream in) throws IOException { int n = Integer.parseInt(header.split(",")[1]); for(int i=0; in; i++){ String s = IOUtils.readLine(in); System.out.println(s); } } public void save(String header, InputStream in) throws IOException{ File dir = new File("ftp"); if(!dir.exists()){ dir.mkdir(); } //header: file,10,filename String[] data = header.split(","); long length = Long.parseLong(data[1]); String filename = data[2]; File file = new File(dir, filename); BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream(file)); for(long i=0; ilength; i++){ int b = in.read(); out.write(b); } out.close(); } }-----------------------------------package javase2.day06.ftp;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;/** * 模拟FTP服务器, 支持命令pwd,ls,get file * * 协议: type,length,value TLV格式 * * 文本: text,5\nline1\nline2\nline3\nline4\nline5\n * 文件: file,4,filename\n 41 42 43 44 * * text,5\nline1\nline2\nline3\nline4\nline5\nfile,4,filename\n 41 42 43 44 */public class FtpServer { public static void main(String[] args) throws IOException{ FtpServer server = new FtpServer(); server.start(); } public void start() throws IOException{ ServerSocket ss = new ServerSocket(9000); while(true){ Socket s = ss.accept(); new Agent(s).start(); } } class Agent extends Thread{ Socket s; public Agent(Socket s) { this.s = s; } public void run() { try{ InputStream in = s.getInputStream(); OutputStream out = s.getOutputStream(); //向客户端发送, 先发协议头,再发送文本行 out.write("text,1\n".getBytes());//协议头 //发送消息内容, 一行文本消息 out.write("欢迎使用FTP演示服务器!\n".getBytes()); out.flush(); while(true){ //读取客户端发送到命令 String cmd = IOUtils.readLine(in).trim(); if("pwd".equals(cmd)){//显示当前目录 pwd(out); }else if("ls".equals(cmd)){ ls(out); }else if(cmd.startsWith("get ")){ get(cmd, out); }else if("bye".equalsIgnoreCase(cmd)){ IOUtils.println(out, "text,1"); IOUtils.println(out, "Bye, Bye!"); s.close(); }else{ out.write("text,1\n".getBytes());//协议头 out.write("只支持pwd,ls,get,bye!\n".getBytes()); out.flush(); } } }catch(IOException e){ e.printStackTrace(); } } } public void pwd(OutputStream out) throws IOException{ File dir = new File("."); IOUtils.println(out, "text,1"); IOUtils.println(out, dir.getCanonicalPath()); } public void ls(OutputStream out) throws IOException{ File dir = new File("."); File[] files = dir.listFiles(); IOUtils.println(out, "text,"+files.length); for (File f : files) { if(f.isDirectory()){ IOUtils.println(out, "["+f.getName()+"]"); }else{ IOUtils.println(out, f.getName()); } } } public void get(String cmd, OutputStream out) throws IOException{ //cmd="get filename" String name = cmd.split("\\s+")[1]; File file = new File(name); if(! file.exists()){ IOUtils.println(out, "text,1"); IOUtils.println(out, "没有文件呀!"+name); return; } //文件协议头: IOUtils.println(out, "file,"+file.length()+","+name); FileInputStream in = new FileInputStream(file); IOUtils.cp(in, out); out.flush(); in.close(); IOUtils.println(out, "text,1"); IOUtils.println(out, "发送成功:"+name); }}
Q3: java中host和post
hosts文件相当于手机tlv格式java代码的电话簿tlv格式java代码,DNS相当于本地的114
hosts是一个没有扩展名的系统文件tlv格式java代码,可以用vi和记事本等工具打开tlv格式java代码,其作用就是将一些常用的域名与其对应的ip
地址建立联系,当用户在浏览器中输入一个需要登陆的网址时,系统会首先从hosts文件中寻找对应的ip地址,一旦找到
系统会立即打开对应的网页,如果没有找到,系统会将网址提交给DNS域名解析服务器进行ip地址的解析,hosts的请求级别比DNS高
DNS的作用跟hosts一样,也是用来解析IP地址的,只不过hosts文件用户可以自由修改,不过DNS上的内容用户是无法修改的,不过用户
可以选择使用哪个DNS服务,一般默认使用电信服务商的,但也可以选择第三方的DNS服务,比如Google,阿里,百度等
http协议
HTTP协议简介
协议规则:内容本身
特点tlv格式java代码:
1.传输过程明文传输,安全性比较差
2.HTTP协议是一种无状态的协议,所以每一个Request都是不相关的
3.应用层协议
HTTP状态码
HTTP协议请求
GET获取服务器的资源
POST在发送信息给服务器,发送信息作为post请求的正文
HTTP响应
HTTP Session
session id 唯一标识客户端,浏览器的身份(服务器分配),服务器后端有一个表就是sessionID对应的的信息(是否已登录,用户名之类的),
保存在服务器端
解决HTTP的无状态
HTTP Cookie
保存在客户端
浏览器读取本地的cookie(通常存放session id)
浏览器访问cookie对应的域名作用域,浏览器将本地存相应域名对应的cookie信息(session id)发送给服务器,服务器过根据session id 找到对应
状态信息
Java实现Get.Post
package cn.itcast.day04.demo01;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class JavaHttpHander {
public static void main(String[] args) {
//sendGet("");
sendPost("","username\t2019216092\n" +
"password\txgh961120\n" +
"execution\t9e0b8d3e-c5b1-4508-b0ab-24c42dd17de4_ZXlKaGJHY2lPaUpJVXpVeE1pSjkuUVRFMFJYWlJaV1pLVVN0SVVHNVhMMk5RYzBoWWNIcG1SV2RaVTJ3d1MwVjJhMmN5Wm14dWFXRlJOSFF3WmpGUlRERkxOWE16VEdkNWJTdDNORVF2VFcxQ1NWTkhTM2x4WjBWWWVUaG1UV1ZLY20wNWVYRTVUVWR2VFRodGJsVmxZelpSYVdvNVkyaEJRWE5rVlc5YWJHaGtUekJ4WVRaeVVUbHNiVEZpT1dwSWFIUjJUVVJNUkdaeVRDdHFOMlZ3YVRsbVJHSkhMM3AzYVU1elVEUlJOMDlUUm5oRlJtVnRNRGxSV25aUGVHZDZOV2t2VFRBemFuaDBZM2hRTTNONVJHUlpaMWR6TlVSTWRGSndZVWhFVFhwdk1XczNja04wTVhoSWFtdHlPRkJ1WkVad056UnJVMnRCU2sxM0swaFZNbWRDU1RScFpGcGlSRXB…U1WQjFPR0kzTDFWT2NYY3JVbk5vV0hKVmFVWm5PRmd4YjNsc1IxbFdSVmxvZDJ0VUx6TjZXSFJ5UTAxemRtbExkMWN3T1dWSlUxRm5WbkJ0ZFZBM2RrcFZaSEpxYUZoVllrcDZUWGxJVFdWMFQwMU1RMmRsYjBkVFRscFJTek00Vkd0WFVTOUphVUo2WWpVNWNrbGxVMWd2U0hWaU1USkZUakZFVTB0UGVtRlhiRVkxZEVSWWNUZEdXV2QxUkVGcWFGWlJjbXR6VDFrMlRucEZaemROVkV4QlppOXRlSEpyVlVsNWNWUm1RMkZ1UkZoT1YyUlVWV014YlZwUWQybE9aVUZZY0hselFVSkxPRlJyTjJSaGN6aGhTVFZxYlcxM1NVWktaRGc5LkxJdE4zNm1CUXMwd2huYzhrUjluczI3Sl90X1d5UkxNUGpHQVJ1dXN3RXpKekhIY3VJX3paVzVnb0RkY1hNOVlLRFkyUmcxblduQXhPODB6UUduMHNB\n" +
"_eventId\tsubmit\n" +
"geolocation\t");
tlv格式java代码的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于、tlv格式java代码的信息别忘了在本站进行查找喔。







