JAVA TCP/IP
2019-08-01 14:15:56 0 举报
AI智能生成
TCP/IP 知识点
作者其他创作
大纲/内容
TCP/IP
套接字关联和数据结构
底层FIFO缓冲区
Local IP
Local Port
Remote IP
Remote Prot
Closed
底层缓冲区可能带来的死锁风险
解决1:在独立线程中实现读写分离
解决2:分阻塞式I/O
应用的缓冲区
write(byte[] buf) -java的buf实际受限和底层的Send-Q
read(byte[] buf) -java的buf实际受限和底层的Recv-Q
性能相关
生命周期
客户端发起链接
服务端等待响应
关闭链接
TCP Socket
TCP的通信原理
TCP使用accept为每一个不同的客户端建立新的通信的Socket
Socket
概述
客户端IP
客户端端口号
API
close方法关闭Socket的输入输出流
shutDownOutput关闭Socket输出流
shutDownInput关闭Socket输入流
Socket Option
Server Socket
构成
服务器端IP
服务器端口号
Socket Option
I/O
InputStream
API
read(byte[] b, int off, int len)
函数解析
方法会阻塞的读取数据
由输出端write输出数据,read并不表示会以一个整体接受数据
read需要调用多次来读取数据
参数解析
b -- 目标字节数组
off -- 在数组b在其中写入数据的起始位置的偏移
len -- 要读取的字节数
返回值解析
该方法返回一个字符为整数。如果流已到达末尾,那么该方法返回-1。
read(byte[] b)
等同与read(b,0,b.length)
available()
返回次输入流下一个方法调用可以不受阻塞地从输入流读取(或跳过)的估计字节数。下一个调可能是同一个线程,也可能是另一个线程。一次读取或跳过此估计数个字节不会受阻塞,但读取或跳过的字节数可能小于该数
readFully(byte[] b)
只有读取len长度个字节的时候才返回。否则阻塞等待,如果超时,则会抛出异常
OutputStream
API
write(byte[] b, int off, int len)
方法解析
将指定byte数组中从偏移量off开始的len个字节写入此输出流
OutputStream的write方法对每个要写出的字节调用一个参数的wrtie方法
子类重写此方法并提供更有效的实现
参数解析
b -- 数据
off -- 在数据偏移的开始
len -- 写入的字节数
write(byte[] b)
等同于write(b, 0, b.length)的效果完全相同
flush()
刷新此输出流并强制写出所有缓冲的输出字节
close()
关闭此输出流并释放与此流有关的所有系统资源
消息边界
TCP传输的数据不一定是以一个整体发送,又以一个整体的方式接收
UDP Socket
UDP的通信原理
UDP服务器端需要显示的设置端口,客户端无需设置
UDP服务器端可以使用同一个套接字与多个客户端通信
DatagramPacket就可以绑定目标地址和端口。DatagramSocket不必要connect目标地址和端口
DatagramPacket
作用:DatagramPacket是发送和接收对象
说明
DatagramPacket.getLength()会在发送或接收数据报文后更新为实际收发数
DatagramPacket在发送和接收数据后不会影响缓冲区的大小和偏移量的位置
DatagramPacket再次接收数据时会根据当前便宜位置覆盖已有的数据
DatagramPacket需要一个足够大的字节缓存数组来容纳接收到的数据
复制getData中的数据,需要注意缓冲数组的偏移位置、大小、实际长度
消息边界
以一个整体的send和receive方法间传递
DatagramPackage最大65507字节
DatagramSocket
DatagramSocket的连接
DatagramSocket的connect()方法是可选
建立连接就只能与该地址通信发送和接收
如果试图发送数据导其他地址会抛出异常
忽略接收来自其他地址和端口发来的信息
常用API
disconnect
断开套接字的连接,如果套接字没有连接,则此方法不执行任何操作
setTimeout
启用/禁用带有指定超时值的SO_TIMEOUT.以毫秒为单位。将此选项设为非零的超时值时,对此DatagramSocket调用receive()将只阻塞此时间长度
send
非阻塞式发送数据报包
receive
此方法在接收到数据报前一直阻塞,数据报包对象的length字段包含所接收信息的长度,如果信息比包的长度长,该信息将被截短
发送和接收数据
信息编码
基本类型-signed
字符串和文本
布尔值编码
Biginteger
可以表示任意大小的数据
但数据的字节长度不确定
可以使用帧的方式来解决
字节数组
ByteOrder
发送方和接收方的字节的顺序的处理方式可能不同
确定little/big-endian哪种数据顺序需要达成一个共识
字节的处理
移位运算符作用
左移或右移运算符此处不是为了数字运算
为了将地位或者高位的字节移动到指定位置
强制byte转换的作用
强制byte转换后保留当前字节顺序的低八位
强制byte转换后舍弃当前字节顺序的高位
byte是有符号的(-128--127),高位和符号位
运算符的作用
配合左移运算符,每次左移使右边空出一个字节的位子,可以将多个单字节连接起来
编码的作用
字节序列可以使用bit-OR(|)操作或bit-AND(&)操作与特定的编码0xff进行运算,实现有符号和无符号的转换
有符号和无符号的转换,java的整数是有符号的
要将有符号和无符号之间转换,可将当前字节放入一个长度默认的数据类型中
这样符号位会更前面的首位置,再使用哪种数据方式取决你的应用需要
通过右移与编码的方式处理数据位,再左移数据位
组合输入输出流
网格的输入输出原理
从网格的一端输出:DataOutputStram->BufferOutPutStream->OutputStream
从网格的一端读取:DataInputStram->BufferInputStream->InputStream
成帧和解析(Framing)
现状
DatagramPacket
负载的数据有确定的长度
接受者能知道消息的结束
TCP
负载的消息没有边界
消息的长度是可变的
每一个字段长度不确定
字段数量不能确定
接收者不能确定数据
消息边界
基于消息定界符
处理流程
消息以一个唯一标识作为结束
但标记不能出现在消息内容中
接收方以字节的方式扫描标记
如消息中出现标记可以用替换
发送发和接收方需要扫描替换
显示的设置消息长度
java特定编码
阻塞和超时
accept、read、receive
ServerSocket-accept()
TCP-read
UDP-receive
write
write在没有足够的写缓冲区时,写操作也会阻塞
直到最后一个字节成功写入到TCP实现的本地缓存
如果可用的缓存控件比要写入的小,在write方法调用返回前,必须把一些数据成功传输到连接的另一端
write的阻塞时间最终取决于接收端
超时和打断write()方法没有提供超时和打断的机制
问题:尝试发送大良数据协议可能会长时间的组成
connect
避免连接阻塞
使用无参数的构造函数创建一个Socket
调用connect指定进程终端和连接时间
解决策略
setSoTimeout会设置一下阻塞方法的最长等待时间
ServerSocket.setSoTimeout()-->accept()
Socker.setSoTimeout()-->read()
Datagram.setSoTimeout()--receive()
Socket.available()->方法会监测Socket是否有可读数据
outTime策略
FAQ
I/O操作避免出现无法读取数据后无限阻塞
关闭连接
Http协议与回显协议的处理
Http的关闭发起者是服务端
回显的关闭发起者是客户端
Http的关闭发起者是服务端
回显的关闭发起者是客户端
Close方法关闭Socket的输入输出流
shutDownOutput关闭Socket输出流(在这之前发送的数据会继续发送到远程接收端,直到读取到-1)
shutDownOutput关闭Socket输入流在这之后不能从输入流读取到数据
Option
Socket:
keepAlive-检查通信的另一端是否活跃
keepAlive-检查通信的另一端是否活跃
Socket/DatagramSocket reveiceBufferSize/sendBUfferSize
建议尺寸,实际情况不一定如此
建议尺寸,实际情况不一定如此
ServerSocket reveiceBufferSize
实际为accept的Socket创建缓冲区
ServerSocket不支持设置sendBufferSize
accept的Socket可以自行设置sendBufferSize
Socket/ServerSocket/DatagramSocketSoTimeout
setSoTimeout会设置一下阻塞方法的最长等待时间
setSoTimeout会设置一下阻塞方法的最长等待时间
ServerSocket.setSoTimeout()->accept();
Socket.setSoTimeout()->read()
Datagram.setSoTimeout()->receive()
Socket/ServerSocket/DatagramSocket ReuserAddress
Socket:TcpNodeply
是否禁止数据缓存延迟功能
不在等待缓冲区满后再发送
Socket:OOBinline-紧急数据
Java的实际情况是不能区分紧急数据
接收方需要开启setOOinline
发送方需要用sendurgentData
Socket:solinger
开启关闭停留功能
Socket:close将等待套接字缓冲区的数据发送完
DatagramSocket:broadcast-广播许可
设置系统是否开启广播
java默认是允许广播开启
Socket/DatagramSocket:TrafficClass-通信等级
实际情况会取决于网络通信商
Socket:perfermancePreFerence-性能服务
连接时间/延时/宽带
参数设置要在建立连接前设置
java会根据参数自动选择适合的协议
0 条评论
下一页