>网络通讯基础
网络通讯要素:IP地址、 端口号、 通信协议
IP地址是网络设备唯一标识。由于IP地址不易记,常用主机名来替代IP地址。默认本机IP地址为127.0.0.1 ,也称本地回环地址,用ping 127.0.0.1命令可以检查本机网卡是否运行正常。
端口号用于标识进程,是进程的逻辑地址。任务管理器中的PID就是进程标识,也即是端口号,不同进程有不同端口号。端口号是一个16位的整数,有效范围是0~65535,其中0~1023这前面1024个端口号是系统保留号,被预先定义的服务通信占用,如23用于Telnet、21用于FTP。
通信协议:网络中实现互相通信需要一些既定的协议,即通信协议,来对传输速率、传输代码、代码结构、传输控制步骤和出错控制等指定标准。
>网络模型
OSI模型通信
TCP/IP参考模型基本称为国际标准,而OSI参考模型没有在Internet上进行广泛推广。
>InetAdress类
IP地址的数字描述网络的层次结构,而域名描述了机器在Internet地址的名称空间中的位置,如www.google.com.Internet域名通过域名服务DNS映射到IP地址。
IntetAddress类用于封装数字化的IP地址及对应的域名,位于java.net包中,直接父类是java.lang.Object类。它有两个子类:
|-Intet4Address |-Intet6Address
Intet4Address类是对IPv4地址的封装
Intet6Address类是对IPv6地址的封装
IntetAddress类没有提供公共的构造器,对应实例不能用new去实例化,但它提供了静态方法getByName()和getByAddress()获取IntelAddress的对象实例
为什么呢?先看构造器源码
/* Constructor for the Socket.accept() method.This
creates an empty InetAddress, which is filled in by the accept()
method. This InetAddress, however, is not put in the address
cache, since it is not created by name.*/
InetAddress() {}
public class InetAddress implements java.io.Serializable {
InetAddress() {}
}
这个空参构造方法是供Socket类的accept()方法用的,它长生一个空InetAddress()对象,该对象会被accept()方法初始化,但是该对象不能被放入缓存,因为没有IP地址名。
java内部把IntelAddress的构造方法私有化了,private IntetAddress(){} 这样就不能访问它的构造函数了,但是我们可以通过InetAddress类里面的静态工厂方法来获得InetAddress对象
static InetAddress getByAddress(byte[] addr)
//Returns an InetAddress object given the raw IP address .
static InetAddress getByAddress(String host, byte[] addr)
//Creates an InetAddress based on the provided host name and IP address.
static InetAddress getByName(String host)
//Determines the IP address of a host, given the host's name.
为什么不直接调用构造函数实例化对象,而用工厂方法(工厂方法自己调用构造函数返回对象)
static InetAddress getByAddress(byte[] addr){
return InetAddress(byte[] addr);
}
这样返回自身对象的方法称为工厂方法。之所以这样设计是静态工厂方法可以随意命名,方法名和参数列表组合,可以明确表达被创建对象的状态,构造函数无此功效。静态方法每次被调用时,不要求非得创建一个新对象,它可以缓存被构造好的对象,避免了每次创建对象的性能开销,如单例模式。
InetAdress常用方法
代码示例
InetAddress iad = InetAddress.getByName("www.google.com");
System.out.println(iad);
//获取InetAddress对象所含对象的主机名(域名)
System.out.println(iad.getHostName());
//获取InetAddress对象所含的IP地址
System.out.println(iad.getHostAddress());
//返回本机域名和IP地址
InetAddress iad2 = InetAddress.getLocalHost();
System.out.println(ida2);
>TCP传输控制协议
^__^三次握手模型
为什么非得握三次手,这手有那么重要吗?
原因是在使用TCP协议时,要建立连接,双方必须确保彼此都存在,形成数据传输通道。第一次、第二次握手是A问好B,B又回应A,此时A能确定B是存在的,因为他刚问完B话,B就回他了,当然能证明B是存在的,但是B却不能判定A是否存在,因为A问完B后可能就自个跑了,也可能还呆原地等着B的反应,具体是那种情况还得看B说完话后A有无回应,只有A再次回话,即有了第三次握手才能确保此时A是存在的。因此,三次握手确保了可靠的传输。Java代码中通过I/O操作,在连接中进行大量数据的传输。此外,传输完毕需要释放已建立的连接。因要确保双方存在(进行三次握手)并建立连接,这使得效率低,速度慢。
>UDP用户数据包协议
特征
1. 将数据、源、目的封装成数据包,无需建立连接;
2. 每次发送的数据包大小限制在64K以内。Java代码中是通过发送端send()方法、接收端receive()方法进行数据传输的;
3. 由于无需连接,故是不可靠的。如果接收端在则数据被接收到,否则数据丢失;
4. 发送数据完成后无需释放资源,所以速度快。
实例举证,生活中的网络聊天、视频会议、桌面共享因其数据传输及时性的要求,因此一般都用UDP协议,而如下载数据因其下载过程要求数据连续,不可中断(否则数据丢失,文件将损坏),故一般使用TCP传输数据更靠谱。