外观
Java网络编程
1.传输层协议
TCP
UDP
上层应用:URL、URL Encode、URL Decode
2.IP地址
1.标志网络设备的唯一标志
2.一台网络设备是可以有多个IP地址的
3.一个IP地址只能对应一个网络设备
3.IP地址的分类
长度
ipv4
4字节,32位
IPv4地址由四段组成,每个字段是一个字节,8位,最大值是255,,
IPv4地址由两部分组成,即网络地址和主机地址。网络地址表示其属于互联网的哪一个网络,主机地址表示其属于该网络中的哪一台主机,二者是主从关系。
IPv4地址的四大类型标识的是网络中的某台主机。IPv4地址长度为32位,共4个字节,但实际中我们用点分十进制记法
IPv4地址根据网络号和主机号来分,分为A、B、C三类及特殊地址D、E。全0和全1的都保留不用,如A类中的0.0.0.0和127.255.255.255都不使用。
A类:(1.0.0.1-126.255.255.254)(默认子网掩码:255.0.0.0或0xFF000000)第一个字节为网络号,后三个字节为主机号,表示为网络--主机--主机--主机。该类IP地址的最前面为“0”,所以地址的网络号取值于1~126之间。共有16777214个主机地址,一般用于大型网络。
B类:(128.1.0.1-191.254.255.254)(默认子网掩码:255.255.0.0或0xFFFF0000)前两个字节为网络号,后两个字节为主机号。该类IP地址的最前面为“10”,所以地址的网络号取值于128~191之间。共有65534个主机地址,一般用于中等规模网络。
C类:(192.0.1.1-223.255.254.254)(子网掩码:255.255.255.0或0xFFFFFF00)前三个字节为网络号,最后一个字节为主机号。该类IP地址的最前面为“110”,所以地址的网络号取值于192~223之间。共有254个主机地址,一般用于小型网络。
D类:是多播地址。(224.0.0.1-239.255.255.254) 该类IP地址的前面4位为“1110”,所以网络号取值于224~239之间;后面28位为组播地址ID。这是一个专门保留的地址。它并不指向特定的网络,目前这一类地址被用在多点广播(Multicasting)中。多点广播地址用来一次寻址一组计算机,它标识共享同一协议的一组计算机。
E类:是保留地址,为将来使用保留。(240.0.0.0---255.255.255.254) 该类IP地址的最前面为“1111”,所以网络号取值于240~255之间。
注意:所有的网络空间计算都必须 -2,这是因为要扣除两个保留地址:
主机号全部为1的地址是子网广播地址,如:192.168.1.255 ;
主机号全部为0的地址是代表该子网的网络地址,如:192.168.1.0 ;
1-254才是给主机使用的。
ipv6
IPv6是英文“Internet Protocol Version 6”(互联网协议第6版)的缩写,是互联网工程任务组(IETF)设计的用于替代IPv4的下一代IP协议,其地址数量号称可以为全世界的每一粒沙子编上一个地址
互联网数字分配机构(IANA)在2016年已向国际互联网工程任务组(IETF)提出建议,要求新制定的国际互联网标准只支持IPv6,不再兼容IPv4。
IP v6与v4区别?
1.地址长度 IPv4协议具有32位(4字节)地址长度;IPv6协议具有128位(16字节)地址长度
地址的表示方法 IPv4地址是以点分割的十进制表示的二进制数。 IPv6地址是以十六进制表示的二进制数。
2.地址配置 IPv4协议的地址可以通过手动或DHCP配置的。 IPv6协议需要使用Internet控制消息协议版本6(ICMPv6)或DHCPv6的无状态地址自动配置(SLAAC)。
3.包的大小 IPv4协议的数据包需要576个字节,碎片可选 。IPv6协议的数据包需要1280个字节,不会碎片
4.包头 IPv4协议的包头的长度为20个字节,不识别用于QoS处理的数据包流,包含checksum,包含最多40个字节的选项字段。
5.IPv6协议的包头的长度为40个字节,包含指定QoS处理的数据包流的Flow Label字段,不包含checksum;IPv6协议没有字段,但IPv6扩展标头可用。
6.地址解析协议 IPv4协议:地址解析协议(ARP)可用于将IPv4地址映射到MAC地址。IPv6协议:地址解析协议(ARP)被邻居发现协议(NDP)的功能所取代。
7.身份验证和加密 IPv6提供身份验证和加密,但IPv4不提供。
4.传输层
保证数据可靠顺序送达
端口:端口号主要运用于传输层上,用来标识同一台计算机中进行通信的不同应用程序(进程)。因此也被成为应用程序地址。
根据端口号识别应用(程序)
TCP的端口和UDP的端口是分开的
TCP 最多有 65536个端口,UDP最多有 65536个端口
0-1024 系统留用
1024-49151 自己定义使用的端口
49152~65535 动态端口
TCP21端口:FTP文件传输服务 TCP23端口:TELNET终端仿真服务 TCP25端口:SMTP简单邮件传输服务 UDP53端口:DNS域名解析服务 TCP80端口:HTTP超文本传输服务 TCP110端口:POP3“邮局协议版本3”使用的端口 TCP443端口:HTTPS加密的超文本传输服务 TCP1521端口:Oracle数据库服务
TCP3306端口:MySQL 数据库服务
TCP8080端口:Tomcat默认使用的端口
5.java进行TCP通信
1.Socket通信(套接字、类似网络管道)
对于网络应用程序,一定分为客户端和服务端2部分
在进行通信过程中,一定要先启动服务端。
进行端口监听。
代码
TCP通信
/**
*服务端
**/
public class TcpServer {
public static void main(String[] args) {
try {
// 建立ServerSocket对象
ServerSocket serverSocket = new ServerSocket(8888);
// 建立服务端Socket对象
System.out.println("服务端监听中....");
Socket socket = serverSocket.accept();
System.out.println("客户端已连接");
// 获取服务端socket对象的输入流
InputStream inputStream = socket.getInputStream();
// 获取服务端socket对象的输出流
OutputStream outputStream = socket.getOutputStream();
// 使用数据流给客户端发送一个字符串
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeUTF("我是服务端");
// 使用数据流获取客户端发来的数据
DataInputStream dataInputStream = new DataInputStream(inputStream);
System.out.println(dataInputStream.readUTF());
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
*客户端
**/
public class TcpClient {
public static void main(String[] args) {
try {
// 建立客户端socket对象
Socket socket = new Socket("127.0.0.1", 8888);
// 获取客户端socke对象的输入流
InputStream inputStream = socket.getInputStream();
// 获取客户端socket对象的输出流
OutputStream outputStream = socket.getOutputStream();
// 使用数据流获取服务端发来的数据
DataInputStream dataInputStream = new DataInputStream(inputStream);
System.out.println(dataInputStream.readUTF());
// 使用数据流给服务端发送数据
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeUTF("收到服务端发送的数据");
System.out.println("收到服务端发送的数据");
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
UDP通信
/**
*服务端
**/
public class UdpServer {
public static void main(String[] args) {
try {
// 创建一个数据报socket对象
DatagramSocket datagramSocket = new DatagramSocket(9999);
System.out.println("wait....");
byte[] buf = new byte[1024];
// 创建一个数据包对象
DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);
// 创建一个字节数组输入流
ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(buf);
// 创建一个字节数组输出流
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
datagramSocket.receive(datagramPacket);
// 服务端接受客户端的数据
DataInputStream dataInputStream = new DataInputStream(arrayInputStream);
System.out.println(dataInputStream.readUTF());
System.out.println("服务端接受成功");
DataOutputStream dataOutputStream = new DataOutputStream(arrayOutputStream);
dataOutputStream.writeUTF("我是服务端发送的数据");
byte[] buff = arrayOutputStream.toByteArray();
datagramSocket.send(new DatagramPacket(buff, buff.length,InetAddress.getByName("127.0.0.1"),9999));
}
catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
*客户端
**/
public class UdpClient {
public static void main(String[] args) {
try {
// 创建一个无连接的datagramSocket对象
DatagramSocket datagramSocket = new DatagramSocket();
// 使用数据流写入
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream(9999);
DataOutputStream dataOutputStream = new DataOutputStream(arrayOutputStream);
dataOutputStream.writeUTF("我是客户端发送的数据");
byte[] buf = null;
buf = arrayOutputStream.toByteArray();
DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length, InetAddress.getByName("127.0.0.1"),9999);
// 客户端发送数据
datagramSocket.send(datagramPacket);
System.out.println("客户端发送成功");
byte[] buff = new byte[1024];
ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(buff);
DataInputStream dataInputStream = new DataInputStream(arrayInputStream);
System.out.println(dataInputStream.readUTF());
datagramSocket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.TCP与UDP的区别
1.都是传输层协议
2.TCP的基于可连接的协议的
2.1建立连接 三次握手协议 建立虚电路
2.2断开连接 四次挥手协议 断开虚电路
3.UDP基于无连接的通信,以恒定的时间发送数据
可单播、多播、广播、不可靠、无拥塞控制
4.TCP类似打电话,UDP类似发短信
5.TCP需要维护长连接(一般通过发送心跳包保持长连接(周期位斐波那契数列))’
6.UDP由于没有握手协议,效率略高
3.BIO,NIO,AIO的区别?
BIO 在JDK1.4出来之前就有的阻塞的Block IO。
NIO 同步非阻塞的NIO
AIO 异步IO 异步非阻塞的AIO。
Java NIO : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。 Java AIO(NIO.2) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理, NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。 AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持 I/O属于底层操作,需要操作系统支持,并发也需要操作系统的支持,所以性能方面不同操作系统差异会比较明显。另外NIO的非阻塞,需要一直轮询,也是一个比较耗资源的。所以出现AIO