IP地址
IPV4
是一个32位的二进制数,通常分为4个字节。表示成a.b.c.d的形式,以点分十进制表示;a、b、c、d都是0~255之间的十进制整数
分为4类
A 0.0.0.0 到 127.255.255.255
B 128.0.0.0 到 191.255.255.255
C 192.0.0.0 到 223.255.255.255
D 224.0.0.0 到 239.255.255.255
D 240.0.0.0 到 247.255.255.255
IPV6
采用128位地址长度,共16个字节,写成8ge无符号整数,每个整数用4个十六进制为表示,树之间用冒号(:)分开
192.168开头的都是私有地址
端口号
可以唯一标识主机中的进程(应用程序)
范围0~65535,公认端口(被预先定义的服务通信占用)0~1023,注册端口(分配给用户进程或应用程序)1024~49151,动态/私有端口:49152~~65535
网络通信协议
通信协议分层思想
同层间可以通信、上一层可以调用下一层,而与再下一层不发生关系
OSI模型
是一个理想的模型、未能广泛推广
应用层 为应用程序提供服务
表示层 数据格式转化、数据加密
会话层 建立、管理和维护会话
传输层 建立、管理和维护端对端的连接
网络层 IP地址及路由选择
数据链路层 提供介质访问和链路管理
物理层 物理传输
TCP/IP模型
是事实上的国际标准
应用层 对应OSI应用层、表示层、会话层;有HTTP、FTP、Telnet、DNS协议
传输层 对应OSI传输层;有TCP、UDP协议
网络层 对应OSI网络层;有IP、ICMP、ARP协议
物理+数据连接层 对应OSI数据链路层、物理层;有Link协议
TCP协议
使用前需要先家里TCP连接,形成基于字节流的传输数据通道
传输前使用3次握手方式,点对点通信,是可靠的
使用重发机制,当另一个通信实体没有确认信息,则会再次重复刚才会送的消息
在连接中可进行大数据量的传输
传输完毕,需释放以建立的连接,效率低
释放连接时需要经过4次挥手
三次握手
第一次握手,客户端向服务器端发起TCP连接的请求;客户端发送syn报文,并置发送序号为X
第二次握手,服务端发送针对客户端TCP连接请求的确认;服务端发送syn+ACK报文,并置发送序号为Y,在确认需要为X+1
第三次握手,客户端发送确认的确认;客户端发送ACK报文,并置发送序号为Z,在确认需要为Y+1
四次挥手
第一次挥手:客户端向服务端提出结束连接,让服务器做最后的准备工作。
此时,客户端处于半关闭状态,即表示不在向服务器发送数据了,但是还可以接受数据;客户端发送Fin+Ack报文,并置发送序号为X
第二次挥手:服务器接收到客户端释放连接的请求后,会将最后的数据发送给客户端。
并告知上层的应用进程不在接收数据;服务端发送ACK报文,并置发送序号为Z,在确认序号为X+1
第三次挥手:服务器发送完数据后,会给客户端发送一个释放连接的报文。那么客户端接收后就知道可以正式释放连接了;
服务端发送Fin+Ack报文,并置发送序号为Y,在确认序号为X。
第四次挥手:客户端接收到服务器最后的释放连接报文,要回复一个彻底断开的报文。这样服务器收到后才会彻底释放连接。
这里客户端,发送完最后的报文后,会等待2MSL。因为有可能服务器没有收到最后的报文,那么服务器迟迟没收到,就会再次给客户端发送释放连接的报文,此时客户端在等待时间范围内接收到,会重新发送最后的报文,并重新计时。
如果等待2MSL后没有收到,那么彻底断开;客户端发送ACK报文,并置发送序号为X,在确认序号为Y
UDP协议
进行通信的两个应用进程:发送端、接收端
将数据、源、目的封装成数据包(传输的基本单位),不需要建立连接
发送不管对方是否准备好,接收方收到也不确认,不能保证数据的完整性,是不可靠的
每个数据报的大小限制在64K内
发送数据结束时无需释放资源,开销小,通信效率高
适用场景:音频、视频和普通数据的传输。例如视频会议
InetAddress类
代表一个IP地址的类
方法
// 获取指定IP地址/域名的InetAddress实例,P地址/域名不存在时会抛UnknownHostException
static InetAddress getByName(String host)
// 获取本机地址的InetAddress实例
static InetAddress getLoclHost()
// 获取域名
getHostName()
// 获取地址
getHostAddress()
Socket类
网络上具有唯一标识的IP地址和端口号组合在一起构成唯一能标识的标识符套接字
方法
// 获取socket的ip地址
InetAddress getInetAddress()
// 表明不在发送数据
shutdownOutput()
示例
public void client() {
try {
InetAddress inetAddress = InetAddress.getLoclHost();
int port = 8989;
Socket socket = new Socket(inetAddress, port);
OutputStream out = socket.getOutputStream();
out.write("你好,我是客户端".getBytes());
} catch (IOException e) {
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
}
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {
}
}
}
public void server() {
try {
int port = 8989;
ServerSocket serverSocket = new ServerSocket(8989);
// 阻塞式的方法
Socket socket = serverSocket.accept();
InputStream is = socket.getInputStream();
byte[] buffer = new byte[1024];
// 内部维护了一个byte数组
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len;
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
System.out.println(baos.toString())
} catch (IOException e) {
} finally {
try {
if (baos != null) {
baos.close();
}
} catch (IOException e) {
}
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
}
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {
}
try {
// 一般来说,服务端不关闭,一直等待客户端发送数据
if (serverSocket != null) {
serverSocket.close();
}
} catch (IOException e) {
}
}
}
发送文件示例
public void client() {
try {
InetAddress inetAddress = InetAddress.getLoclHost();
int port = 8989;
Socket socket = new Socket(inetAddress, port);
File file = new File("pic.jpg");
FileInputStream fileInputStream = new FileInputStream(file);
OutputStream out = socket.getOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
socket.shutdownOutput();
InputStream is = socket.getInputStream();
byte[] buffer1 = new byte[1024];
// 内部维护了一个byte数组
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len;
while ((len = is.read(buffer1)) != -1) {
baos.write(buffer1, 0, len);
}
System.out.println(baos.toString())
} catch (IOException e) {
} finally {
try {
if (baos != null) {
baos.close();
}
} catch (IOException e) {
}
try {
if (fileInputStream != null) {
fileInputStream.close();
}
} catch (IOException e) {
}
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
}
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
}
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {
}
}
}
public void server() {
try {
int port = 8989;
ServerSocket serverSocket = new ServerSocket(8989);
// 阻塞式的方法
Socket socket = serverSocket.accept();
InputStream is = socket.getInputStream();
byte[] buffer = new byte[1024];
File file = new File("pi1c.jpg");
FileOutputStream fileOutputStream = new FileOutputStream(file);
int len;
while ((len = is.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, len);
}
OutputStream out = socket.getOutputStream();
out.write("服务端已接收".getBytes());
} catch (IOException e) {
} finally {
try {
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
}
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
}
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
}
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {
}
try {
// 一般来说,服务端不关闭,一直等待客户端发送数据
if (serverSocket != null) {
serverSocket.close();
}
} catch (IOException e) {
}
}
}
DatagramScoket类
public void sender() {
DatagramScoket datagramScoket = new DatagramScoket();
InetAddress inetAddress = InetAddress.getLoclHost();
int port = 8989;
byte[] bytes = "我是发送端".getBytes();
// 打包要发送的数据报,包含要发送的数据和接受端的ip和端口
DatagramPacket packet = new DatagramPacket(bytes, 0 bytes.length, inetAddress, port);
datagramScoket.send(packet);
datagramScoket.close();
}
public void receiver() {
int port = 8989;
DatagramScoket datagramScoket = new DatagramScoket(port);
byte[] bytes = new byte[1024 * 64];
// 创建数据报的对象,用于接收发送端发送过来的数据
DatagramPacket packet = new DatagramPacket(bytes, 0 bytes.length);
datagramScoket.receive(packet);
byte[] recData = packet.getData();
System.out.println(new String(recData, 0, recData.getLength()))
datagramScoket.close();
}
URL
统一资源定位符,一个具体的url就对应着互联网上某一资源的地址
URL类
方法
// 创建一个url地址的类
URL url = new URL(String str);
// 获取该URL的协议名
String getProtocol()
// 获取该URL的主机名
String getHost()
// 获取该URL的端口号
String getPort()
// 获取该URL的文件路径
String getPath()
// 获取该URL的文件名
String getFile()
// 获取该URL的查询名
String getQuery()
// 获取url连接
URLConnection openConnection()
URLConnection类
// 获取输入流
InputStream getInputStream()
// 关闭url连接
disconnect()