14Java进阶网络编程API
1.网络协议的三要素:语义、语法和时序
语义表示要做什么,语法表示要怎么做,时序表示做的顺序。
2.网络OSI七层模型
OSI/RM 模型(Open System Interconnection/Reference Model)。它将计算机网络体系结构的通信协议划分为七层,自下而上依次为物理层(Physics Layer)、数据链路层(Data Link Layer)、网络层(Network Layer)、传输层(Transport Layer)、会话层(Session Layer)、表示层(Presentation Layer)、应用层(Application Layer)。
3.TCP四层模型简介
自下而上依次为网络接口层(Network Interface Layer)、网络层(Network Layer)、传输层(Transport Layer)和应用层(Application Layer)。
还可以转换为五层模型,即将网络接口层分为物理层和数据链路层。
3.1TCP四层作用
物理层规定了物理介质的各种特性,包括机械特性、电子特性、功能特性和规程特性。
数据链路层负责接收数据帧并通过网络发送,或从网络上接收物理帧再抽离出数据帧交给网络层。
网络层管理网络中的数据通信,设法将数据从源端经过若干中间节点传送到目的端,从而向传输层提供最基本的端到端的数据传送服务。
传输层主要功能包括分割和重组数据并提供差错控制和流量控制,以达到提供可靠传输的目的。为了实现可靠的传输,传输层协议规定接收端必须发送确认信息以确定数据达到,假如数据丢失,必须重新发送。
应用层对应于 OSI 七层模型的会话层、表示层和应用层,该层向用户提供一组常用的应用程序服务。
3.2传输层的常用协议
1.传输控制协议(Transmission Control Protocol,TCP),是一种可靠的面向连接的传输服务协议。在 TCP/IP 协议族中,TCP 提供可靠的连接服务,采用“三次握手”建立一个连接。
2.用户数据报协议(User Datagram Protocol,UDP),是另外一个重要的协议,它提供的是无连接、面向事务的简单不可靠信息传送服务。UDP 不提供分割、重组数据和对数据进行排序的功能,也就是说,当数据发送之后,无法得知其是否能安全完整地到达。
UDP是无连接的、不可靠的,资源消耗小,处理速度快,但是在网络不好的情况下丢包比较严重。
3.3应用层的常用协议
-
文件传输协议(File Transfer Protocol,FTP),上传、下载文件可以使用 FTP 服务。
-
Telnet 协议,提供用户远程登录的服务,使用明码传送,保密性差,但简单方便。
-
域名解析服务(Domain Name Service,DNS),提供域名和 IP 地址之间的解析转换。
-
简单邮件传输协议(Simple Mail Transfer Protocol,SMTP),用来控制邮件的发送、中转。
-
超文本传输协议(Hypertext Transfer Protocol,HTTP),用于实现互联网中的 WWW 服务。
-
邮局协议的第三个版本(Post Office Protocol 3,POP3),它是规定个人计算机如何连接到互联网上的邮件服务器进行收发邮件的协议。
3.4数据的封装与解封
从上向下,数据的传输需要加上相应的头部和尾部,称为数据的封装。
从下向上,数据的传输需要去掉相应的头部和尾部,称为数据的解封。
4 IP地址及其表示
IP地址由两部分组成:网络号和主机号
网络号表示该地址处于哪一个网络,主机号表示该地址的主机。
IP 地址有两种表示方式,二进制表示和点分十进制表示,常见的是点分十进制表示的 IP 地址。IP 地址的长度为 32 位,每 8 位组成一个部分,一个 IP 地址可以分为四个部分。如果每个部分用十进制表示,其值的范围为 0 ~ 255,不同部分之间用“.”分割开来。
5 域名简介及其分类
域名可分为不同级别,包括顶级域名、二级域名等。
顶级域名又可分为以下两类:
一类是国家顶级域名,200 多个国家都按照 ISO3166 国家代码分配了顶级域名,例如中国是 cn,美国是 us,韩国是 kr 等。
另一类是国际顶级域名,一般表示着注册企业类别的符号,例如表示工商企业的 com,表示网络提供商的 net,表示非营利组织的 org 等。
二级域名是指顶级域名之下的域名,例如在国际顶级域名下,由域名注册人申请注册的网上名称,例如 sohu、apple、microsoft 等。
6 InetAddress——获取IP地址
-
InetAddress[] getAllByName(String host)
:通过主机名和配置名返回IP地址。 -
InetAddress getByAddress(byte[] addr)
:通过 IP 地址数组返回InetAddress
对象。 -
InetAddress getByAddress(String host, byte[] addr)
:根据提供的主机名 host 和字节数组形式的 IP 地址 addr,创建InetAddress
对象。 -
InetAddress getByName(String host)
:给定主机名 host,返回InetAddress
对象。 -
InetAddress getLocalHost()
:返回本地主机InetAddress
对象。
InetAddress
类的其他常用方法有以下几种:
-
byte[] getAddress()
:返回此InetAddress
对象的 IP 地址数组。 -
String getCanonicalHostName()
:返回此 IP 地址的完全限定域名。完全限定域名是指主机名加上全路径,全路径中列出了序列中所有域成员。 -
String getHostAddress()
:返回 IP 地址字符串。 -
String getHostName()
:返回此 IP 地址的主机名。
7 URL类——获取网络资源的位置
构造方法:URL(地址)
获取页面的输入字节流:url.openStream()
使用IO方法对页面的内容进行获取和解析
8 URLConnection类——连接通信
1.使用url.openConnection()获取连接对象。
2.设置参数和一般请求属性。
3.使用connect()方法进行远程连接。
8.1 URLConnection的具体属性
-
boolean doInput
:将doInput
标志设置为 true,指示应用程序要从 URL 连接读取数据,此属性的默认值为 true。此属性由setDoInput()
方法设置,其值由getDoInput()
方法返回。 -
boolean doOutput
:将doOutput
标志设置为 true,指示应用程序要将数据写入 URL 连接,此属性的默认值为 false。此属性由setDoOutput()
方法设置,其值由getDoOutput()
方法返回。 -
boolean useCaches
:如果其值为 true,则只要有条件就允许协议使用缓存;如果其值为 false,则该协议始终必须获得此对象的新副本,其默认值为上一次调用setDefaultUseCaches()
方法时给定的值。此属性由setUseCaches()
方法设置,其值由getUseCaches()
方法返回。 -
boolean connected
:表示URL是否连接成功 -
URL url
:表示Connection类在网上打开的url对象。
9 使用Socket编程之TCP Socket
Socket:套接字,用于端到端的通信。
ServerSocket:用于服务端对象的创建。服务器会初始化一个端口号的Socket,监听此端口的连接。如果客户端建立连接,会分配一个带有新的端口号的Socket,用来和客户端对话。当连接结束时,会关闭Socket。
ServerSocket的accept()方法:ServerSocket的accept()方法从连接请求队列中取出一个客户的连接请求,然后创建与客户连接的Socket对象,并将它返回。如果队列中没有连接请求,accept()方法就会一直等待,直到接收到了连接请求才返回。
服务器为请求连接的客户进程建立一个先进先出队列,默认大小一般是50,如果调用accept()方法就会从队列中取出连接请求,服务端为其建立一个socket。如果队列已经满,服务器会拒绝新的连接请求。
9.1使用Socket创建CS连接
package two; import java.io.DataInputStream; import java.io.IOException; import java.net.ConnectException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; public class Test7 { } class TestServer{ public static void main(String[] args) { ServerSocket socket = null; try { //创建服务端的socket socket = new ServerSocket(8888); //创建一个socket,接受客户端的套接字 Socket s = socket.accept(); //显示 System.out.println("客户端的IP:"+s.getInetAddress()+",客户端的端口号:"+s.getPort()); s.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } class TestClient{ public static void main(String[] args) { try { //服务端和客户端在同一局域网内。服务端的端口号是8888 Socket socket = new Socket("127.0.0.1",8888); //从socket中获得客户端的端口号和IP DataInputStream dis = new DataInputStream(socket.getInputStream()); if(dis.available()!=0)System.out.println(dis.readUTF()); dis.close(); socket.close(); }catch (ConnectException e) { e.printStackTrace(); System.err.println("服务器连接失败!"); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }