1.UDP
用户数据报协议(User Datagram Protocol)。
数据报(Datagram):网络传输的基本单位
UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。
由于使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输例如视频会议都使用UDP协议,因为这种情况即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。
但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,因此在传输重要数据时,不建议使用UDP协议。
特点:数据被限制在64kb以内,超出这个范围就不能发送了。
2.TCP
传输控制协议(Transmission Control Protocol)。
TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。
在TCP连接中必须要明确客户端与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”。
三次握手
TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠。
第一次握手: SYN=1 seq=x.SYN=1,ACK=0.表示为请求连接报文,(这里ACK=0省略)
seq表示主机A向主机B协商从序号为x发送数据报
这里需要注意的是,A向B的连接未建立无法传送数据,所以该请求报文消耗序号最小,消耗1个序号
第二次握手 SYN=1,ACK=1,seq=y,ack=x+1。
SYN=1,ACK=1表示同意建立A向B的连接,seq=y表示从序号为y的报文段开始发送,
ack=x+1表示已收到序号x的报文段,期望收到x+1序号的数据,即已收到序号x。第一次的请求报文消耗了1个序号
ack=x+1确认了第一次报文的收到,并请求B向A的连接
第三次握手 SYN=1,ACK=1,seq=x+1,ack=y+1 。
seq=x+1表示自己从序号x+1开始发送,期望收到主机B序号y+1的数据
第三次报文确认了前两次请求报文的收到。
四次挥手
第一次挥手 FIN=1表示请求关闭A向B的连接 seq=u 已发送u-1序号的数据报
第二次挥手 ACK=1,同意关闭A向B的连接。seq=v,B向A发送的数据报序号为v。ack=u+1已收到u序号数据报
此时A向B方向的连接已经关闭,中间保持一段时间单向B向A连接
第三次挥手 FIN=1 seq=w
FIN=1,请求关闭B向A连接。seq=w,从序号为w开始向A发送。
这里ack=u+1是因为前两次已经关闭了客户向服务器这个方向的链接。
第四次挥手 ACK=1,seq=u+1,ack=w+1。
ACK=1,同意关闭B向A连接。seq=u+1,因为A向B的连接已关闭,故这里是u+1。ack=w+1,已收到序号w的报文段,期望收到w+1序号的报文段。
为什么挥手需要四次?
关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。服务器收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK 和 FIN 一般都会分开发送,从而比三次握手导致多了一次
通俗理解: |
- 三次握手 A:我要过来了!B:我知道你要过来了!A:我现在过来!
- 四次挥手 A:我们分手吧!B:真的分手吗?B:真的真的要分手吗?A:是的!
由此,可以可靠地进行连接和断开。
四、IP协议
(一)IP协议的的概念
每个人的电脑都有一个独一无二的IP地址,这样互相通信时就不会传错信息了。
(二)IP地址的分类
IP地址根据版本可以分类为:IPv4和IPv6
IPv4又可以分为五类:
A类:在IP地址的四段号码中,第一段号码为网络号码,剩下的三段号码为本地计算机的号码;A类IP地址中网络的标识长度为8位,主机标识的长度为24位,A类网络地址数量较少,有126个网络,每个网络可以容纳主机数达1600多万(256的三次方-2)台。
B类:在IP地址的四段号码中,前两段号码为网络号码。B类IP地址中网络的标识长度为16位,主机标识的长度为16位,B类网络地址适用于中等规模的网络,有16384个网络,每个网络所能容纳的计算机数为6万多(256的二次方-2)台
C类:在IP地址的四段号码中,前三段号码为网络号码,剩下的一段号码为本地计算机的号码;此类地址中网络的标识长度为24位,主机标识的长度为8位,C类网络地址数量较多,有209万余个网络。适用于小规模的局域网络,每个网络最多只能包含254(256-2)台计算机
D类:此类IP地址在历史上被叫做多播地址(multicast address),即组播地址;在以太网中,多播地址命名了一组应该在这个网络中应用接收到一个分组的站点;多播地址的最高位必须是“1110”,范围从224.0.0.0到239.255.255.255
E类: 此类地址也不分网络地址和主机地址,它的第1个字节的前五位固定为“11110”,为将来使用保留,地址范围从240.0.0.1到255.255.255.254-
(三)Java InetAddress类
说到IP地址,就要引入一个类:InetAddress
此类表示互联网协议 (IP) 地址。
特别说明: InetAddress类无构造方法
常用方法摘要
方法名 | 实现功能 |
byte[] getAddress() | 返回此 InetAddress 对象的原始 IP 地址。 |
static InetAddress getByName(String host) | 在给定主机名的情况下确定主机的 IP 地址。 |
String getHostAddress() | 返回 IP 地址字符串(以文本表现形式)。 |
String getHostName() | 获取此 IP 地址的主机名。 |
static InetAddress getLocalHost() | 返回本地主机。 |
127.0.0.1:本机地址,主要用于测试。别名:Localhost
测试样例一
import java.net.InetAddress; import java.net.UnknownHostException; public class TestIP { public static void main(String[] args) throws UnknownHostException { //InetAddress类表示IP地址 //获取本机IP InetAddress ip = InetAddress.getLocalHost(); System.out.println(ip); //Cdy-Pc/192.168.43.99 //获得主机名 System.out.println(ip.getHostName()); //Cdy-Pc //获得ip地址 System.out.println(ip.getHostAddress());//192.168.43.99 //查找主机名为xxx的IP地址 System.out.println(InetAddress.getByName("localhost")); //localhost/127.0.0.1 //其中127.0.0.1为默认本机的主机地址 } }
测试样例二
import java.net.InetAddress; import java.net.UnknownHostException; public class TestIP2 { public static void main(String[] args) throws UnknownHostException { InetAddress inetAddress = InetAddress.getByName("www.baidu.com"); // 获取此 IP 地址的主机名。 System.out.println(inetAddress.getHostName()); //返回 IP 地址字符串(以文本表现形式)。 System.out.println(inetAddress.getHostAddress()); } }
五、端口
IP地址用来标识一台计算机,但是一台计算机上可能提供多种网络应用程序,如何来区分这些不同的程序呢?这就要用到端口。端口号是用来区分一台机器上不同的应用程序的。
我们使用IP地址加端口号,就可以保证数据准确无误地发送到对方计算机的指定软件上了。
端口是虚拟的概念,是一个逻辑端口。
当我们使用网络软件一打开,那么操作系统就会为网络软件分配一个随机的端口号,或者打开的时候向系统要指定的端口号。
通过端口,可以在一个主机上运行多个网络应用程序。端口的表示是一个16位的二进制整数,2个字节,对应十进制的0~65535。
端口号在计算机内部是占2个字节。一台机器上最多有65536个端口号。一个应用程序可以占用多个端口号。端口号如果被一个应用程序占用了,那么其他的应用程序就无法再使用这个端口号了。
记住一点,我们编写的程序要占用端口号的话占用1024以上的端口号,1024以下的端口号不要去占用,因为系统有可能会随时征用。端口号本身又分为TCP端口和UDP端口,TCP的8888端口和UDP的8888端口是完全不同的两个端口。TCP端口和UDP端口都有65536个。
(一)端口分类
公有端口:0~1023
1.HTTP:80
2.HTTPS:443
3.FTP:21
4.Telnet:23
.程序注册端口(分配给用户或者程序):1024~49151
Tomcat:8080
MySQL:3306
Oracle:1521
动态、私有端口:49152~65535
(二)DOS命令查看端口
- 查看所有端口:
netstat -ano
- 查看指定端口:
netstat -ano|findstr "端口号"
- 查看指定端口的进程:
tasklist|findstr "端口号"
(三)InetSocketAddress类
说到端口,则要引入一个类:InetSocketAddress
此类实现 IP 套接字(Socket)地址(IP 地址 + 端口号)。
1.构造方法摘要
InetSocketAddress(InetAddress addr, int port)
根据 IP 地址和端口号创建套接字地址。
InetSocketAddress(int port)
创建套接字地址,其中 IP 地址为通配符地址,端口号为指定值。
InetSocketAddress(String hostname, int port)
根据主机名和端口号创建套接字地址。
2.常用方法摘要
InetAddress getAddress()
获取 InetAddress。
String getHostName()
获取 hostname。
int getPort()
获取端口号。
演示案例
import java.net.InetSocketAddress; public class Testport { public static void main(String[] args) { InetSocketAddress inetSocketAddress = new InetSocketAddress("8.8.8.8", 8082); System.out.println(inetSocketAddress); System.out.println(inetSocketAddress.getAddress()); System.out.println(inetSocketAddress.getHostName()); System.out.println(inetSocketAddress.getPort()); } }