文章目录
网络模型
OSI 参考模型:ISO 国际标准化组织定义的模型,是一种 通讯层次的划分。
TCP/IP 参考模型:目前最为主流的网络模型。
网络模型 7 层概述:
- 物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型各种传输介质的传输速率等。它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后在转化为1、0,也就是我们常说的数模转换与模数转换)。这一层的数据叫做比特。
- 数据链路层:主要将从物理层接收的数据进行MAC地址(网卡的地址)的封装与解封装。常把这一层的数据叫做帧。在这一层工作的设备是交换机,数据通过交换机来传输。
- 网络层:主要将从下层接收到的数据进行IP地址(例192.168.0.1)的封装与解封装。在这一层工作的设备是路由器,常把这一层的数据叫做数据包。
- 传输层:定义了一些传输数据的协议和端口号(WWW端口80等),如:TCP(传输控制协议,传输效率低,可靠性强,用于传输可靠性要求高,数据量大的数据),UDP(用户数据报协议,与TCP特性恰恰相反,用于传输可靠性要求不高,数据量小的数据,如QQ聊天数据就是通过这种方式传输的)。 主要是将从下层接收的数据进行分段和传输,到达目的地址后再进行重组。常常把这一层数据叫做段。
- 会话层:通过传输层(端口号:传输端口与接收端口)建立数据传输的通路。主要在你的系统之间发起会话或者接受会话请求(设备之间需要互相认识可以是IP也可以是MAC或者是主机名)
- 表示层:主要是进行对接收的数据进行解释、加密与解密、压缩与解压缩等(也就是把计算机能够识别的东西转换成人能够能识别的东西(如图片、声音等)。
- 应用层: 主要是一些终端的应用,比如说FTP(各种文件下载),WEB(IE浏览),QQ之类的(可以把它理解成我们在电脑屏幕上可以看到的东西.就是终端应用)。
TCP/IP 模型
TCP/IP 协议
- TcpIp 协议是目前世界上应用最为广泛的协议
- 是以 TCP 和 IP 为基础的不同侧次上多个协议的集合
- 也叫:TcpIp协议族 或 TcpIp 协议栈
- Tcp :Transmission Control Protocol 传输控制协议
- IP :Internet Protocol 互联网协议
网络通讯三要素
- IP地址
- 端口
- 传输协议
IP地址
- 定义:为了实现网络中不同计算机之间的通信,每台计算机都必须有一个唯一标识–IP地址。
- 格式:目前使用较多的 IPv4 格式的 IP地址 :由四组 范围在 0-255 的数字组成,中间使用
.
分割,eg:127.0.0.1
IPv6 是 IPv4 的扩展,提供了更大范围的标识。
- 主机名/域名:为了解决 IP 地址不便记忆的问题,使用主机名/域名 为 IP地址提供了 别名,eg:本机回环地址
127.0.0.1
的主机名 为localhost
。 注意:主机名/域名 可重复表示不同的 IP地址 ,亦即是:主机名/域名 和 IP地址是 一对多 的关系。
A. 计算机只能识别二进制的数据,所以我们的IP地址应该是一个二进制的数据。
但是呢,我们配置的IP地址确不是二进制的,为什么呢?
- IP:192.168.1.100
- 换算:11000000 10101000 00000001 01100100
假如真是:11000000 10101000 00000001 01100100的话。
我们如果每次再上课的时候要配置该IP地址,记忆起来就比较的麻烦。
所以,为了方便表示IP地址,我们就把IP地址的每一个字节上的数据换算成十进制,然后用.分开来表示: “点分十进制”
B. IP地址的组成:网络号段+主机号段
- A类:第一号段为网络号段+后三段的主机号段
一个网络号:256256256 = 16777216 - B类:前二号段为网络号段+后二段的主机号段 (校园网)
一个网络号:256*256 = 65536 - C类:前三号段为网络号段+后一段的主机号段(最常见)公司
一个网络号:256
C. IP地址的分类:
-
A类 1.0.0.1—127.255.255.254 (美地占用,国内三个:政府、电信、军工)
- (1)
10.X.X.X是私有地址
(私有地址就是在互联网上不使用,而被用在局域网络中的地址,可能公司的局域网) - (2)127.X.X.X是保留地址,用做循环测试用的。
- (1)
-
B类 128.0.0.1—191.255.255.254 (校园网)
- 172.16.0.0—172.31.255.255是私有地址(公司不常用)。169.254.X.X是保留地址。
-
C类 192.0.0.1—223.255.255.254 (最常见)
192.168.X.X是私有地址
(局域网中使用,比如本机地址是:192.168。1.103)
-
D类 224.0.0.1—239.255.255.254
-
E类 240.0.0.1—247.255.255.254
D. 两个DOS命令:
ipconfig
查看本机ip地址ping
后面跟ip地址。测试本机与指定的ip地址间的通信是否有问题
E. 特殊的IP地址:
127.0.0.1
回环地址,可用于测试本机的网络是否有问题.ping 127.0.0.1
- x.x.x.255 广播地址
- x.x.x.0 网络地址
端口
-
定义:用于区分计算机上的不同应用程序
-
范围:0-65535,其中 0-1024 为系统保留端口。
-
Socket :IP地址和端口号组成了Socket,Socket是网络上的程序之间双向通信链路的终结点/终端,是TCP和UDP的基础。
类比电话号码的主机号和分机号:
- 021-50215021 是 二工大主机
- 021-50215021 转 7729 学生处
- 021-50215021 转 7723 财务处
-
默认端口号:
- HTTP:80
- FTP:21
- Telnet:23
-
小案例:公司不可使用 QQ 原理:防火墙禁掉 QQ的端口号,进而 禁止 QQ 传输数据。
传输协议
-
定义:通讯的统一规则
-
常见协议:
- TCP 协议:(三次握手协议)
- 需要建立连接,形成传输数据的通道
- 连接中,可进行大量数据的传输,不受限制
- 三次握手完成确认连接,可靠协议
- 必须建立连接,效率会降低(相对UDP)
- UDP 协议:(不可靠协议)
- 不需要建立连接。将数据源和目的地封装到数据报中。
- 类比平信(接收方不知道有发送;发送方不知道接收方是否接收)
- 每个数据报限制在 64 KB
- 不需要建立连接,是不可靠协议
- 不需要建立连接,效率较高(相对TCP)
- 不需要建立连接。将数据源和目的地封装到数据报中。
- TCP 协议:(三次握手协议)
Java中的网络支持
针对网络层次的不同,Java提供的网络功能有四大类:
- InetAddress : 用于标识网络上的资源
- URL :统一资源定位符 通过URL可以直接读取或写入网络上的数据
- Socket :使用TCP协议实现网络通信的Socket相关的类
- Datagram :使用UDP协议,将数据存在数据报中,通过网络进行通信
InetAddress
类描述
InetAddress 用于标识网络上的硬件资源,表示互联网协议(IP)地址
IP 地址是 IP 使用的 32 位或 128 位无符号数字,它是一种低级协议,UDP 和 TCP 协议都是在它的基础上构建的。InetAddress 的实例包含 IP 地址,还可能包含相应的主机名(取决于它是否用主机名构造或者是否已执行反向主机名解析)。
反向名称解析 意味着对于任何 IP 地址,都返回与 IP 地址关联的主机。
InetAddress 类提供将主机名解析为其 IP 地址(或反之)的方法。
方法描述
无构造方法,为了安全性。
使用 一次下方法创建 一个或一组 InetAddress 实例:推荐 getByName()
,时而使用**getLocalHost()
**
public static InetAddress getLocalHost() throws UnknownHostException
使用本地主机创建 一个 InetAddress 对象,返回的主机名是 本地计算机名称public static InetAddress getByAddress(byte[] addr) throws UnknownHostException
使用长度为 4 的字节数组 表示的 IP 地址 创建 InetAddress 对象public static InetAddress getByAddress(String host, byte[] addr) throws UnknownHostException
指定主机名(自定义)和IP地址,创建一个 InetAddress 对象public static InetAddress getByName(String host) throws UnknownHostException
使用 指定主机名或 IP 地址 或者本机回环地址或者本机计算机名 创建一个 InetAddress ,默认 IP地址创建时,主机名 使用 IP地址表示public static InetAddress[] getAllByName(String host) throws UnknownHostException
使用指定的主机名,创建一组 InetAddress 对象。根据 主机名 和 IP 地址的多对一关系。
常用方法:
public String getHostName()
Gets the host name for this IP address.public byte[] getAddress()
Returns the raw IP address of this InetAddress object.public String getHostAddress()
Returns the IP address string in textual presentation.(文本表示)public String toString()
返回的是getHostName+'/'+getHostAddress
可能需要配合的方法:Arrays 的 toString 方法,String类的 getBytes方法
URL
类描述
URL (Uniform Resource Locator)统一资源定位符,表示Internet上某一资源的地址
URL 由两部分组成:协议名称和资源名称,中间使用冒号隔开
在 java.net 中 提供了 URL类 来表示 URL
类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。
绝对URL主要组成部分:必选的 协议、主机名、端口号(不主动提供时,使用默认端口号)、资源路径(文件名称),可选内容
URL 后面可能还跟有一个“片段”,也称为“引用”,或者 “锚点”。该片段由井字符 “#” 指示,后面跟有更多的字符。例如: http://java.sun.com/index.html#chapter1
从技术角度来讲,URL 并不需要包含此片段。但是,使用此片段的目的在于表明,在获取到指定的资源后,应用程序需要使用文档中附加有 chapter1 标记的部分内容。标记的含义取决于资源,例如对于HTML页面来说,可能是一个 页面内的链接,指定页面的 特定内容。
例如:http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#MIN_VALUE
锚点 指示 内容是 Integer 的最大值 字段属性在Integer.html页面中的位置
相对 URL 不需要指定 URL 的所有组成部分。如果缺少协议、主机名称或端口号,这些值将从完整指定的 URL 中继承。但是,必须指定文件部分。可选的片段部分不继承。
URL 类自身并不根据 RFC2396 中定义的转义机制编码或解码任何 URL 部分。它不会识别同一 URL 的对等编码和解码形式。
例如,对于这两个 URL:http://foo.com/hello world/
和 http://foo.com/hello%20world
将被视为互不相等。
注意
,URI 类在某些特定情况下对其组成字段执行转义。建议使用URI
管理URL
的编码和解码,并使用toURI()
和URI.toURL()
实现这两个类之间的转换。
方法描述
从该类的构造方法中就可以很容易知道,URL 的组成部分:推荐使用 URL(String spec)
URL(String spec)
根据 String 表示形式创建 URL 对象。
eg : new URL(“http://static.rupeng.com/static/imgs/logo-1.png”)URL(String protocol, String host, int port, String file)
根据指定 protocol、host、port 号和 file 创建 URL 对象。
eg : new URL(“http”,“static.rupeng.com”,“80”,“static/imgs/logo-1.png”);URL(String protocol, String host, String file)
根据指定的 protocol 名称、host 名称和 file 名称创建 URL。使用 默认端口
URL(URL context, String spec)
通过在指定的上下文中对给定的 spec 进行解析创建 URL。使用 相对 URL
:协议、主机名、端口可继承 context 。可选片段不可继承。
常用方法:
- 获取协议:
public String getProtocol()
- 获取主机名:
public String getHost()
- 获取端口:
public int getPort()
返回 -1 表示未提供,使用 默认端口 - 获取文件路径:
public String getPath()
- 获取文件名:
public String getFile()
- 获取锚点/片段:
public String getRef()
- 获取查询字符串:
public String getQuery()
- 获取用户信息:
public String getUserInfo()
- 返回
null
,表示该部分不存在
TCP 编程
TCP 协议是面向连接的,可靠的,有序的 ,以字节流方式发送数据
基于 TCP 实现网络通信的类:
- 客户端的 Socket类
- 服务器端的 ServerScocket类
Socket 通信
回顾:IP地址和 端口号 组成了Socket。
Socket 通信步骤:
- 创建 ServerSocket 和 Socket 对象
- 打开、连接到Socket的输入输出流
- 按照协议对Socket进行读写操作
- 关闭输入输出流和Socket对象
服务器
- 创建 ServerSocket 对象,绑定监听借口(避免 0-1023)
- 通过 accept() 方法监听客户端的请求
- 连接建立之后,通过输入流读取客户端发送的请求信息
- 通过输出流向客户端发送响应信息
- 关闭相关资源
ServerSocket 类
-
类描述:
此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。
服务器套接字的实际工作由 SocketImpl 类的实例执行。应用程序可以更改创建套接字实现的套接字工厂来配置它自身,从而创建适合本地防火墙的套接字。 -
常用方法:
-
构造器:常用推荐
ServerSocket(int port)
ServerSocket()
创建非绑定服务器套接字。ServerSocket(int port)
创建绑定到特定端口的服务器套接字。ServerSocket(int port, int backlog)
利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。ServerSocket(int port, int backlog, InetAddress bindAddr)
使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。
-
监听功能
public Socket accept() throws IOException
监听客户端的连接,返回的客户端套接字对象(是有一个阻塞方法)
-
绑定功能
public void bind(SocketAddress endpoint) throws IOException
将 ServerSocket 绑定到特定地址(IP地址和端口号)
-
获取功能
public int getLocalPort()
获取 端口号,-1表示未指定,使用默认端口。public InetAddress getInetAddress()
获取 IP 地址的对象public SocketAddress getLocalSocketAddress
获取 套接字地址对象,包括 getLocalPort 和 getInetAddress 的内容
-
关闭功能
public void close() throws IOException
关闭套接字
-
客户端
- 创建 Scoket 对象,指明需要连接的服务器的IP地址和端口号
- 连接建立后,通过 输出流向服务器发送请求信息
- 通过输入流获取服务器的响应信息
- 关闭相关资源
Scoket 类:
-
类描述:
此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点/终结点
。
套接字的实际工作由 SocketImpl 类的实例执行。应用程序通过更改创建套接字实现的套接字工厂可以配置它自身,以创建适合本地防火墙的套接字。 -
常用方法:
- 构造器:
Socket()
通过系统默认类型的 SocketImpl 创建未连接套接字Socket(InetAddress address, int port)
创建一个流套接字并将其连接到指定 IP 地址的指定端口号。Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
创建一个套接字并将其连接到指定远程地址上的指定远程端口。Socket(String host, int port)
创建一个流套接字并将其连接到指定主机上的指定端口号。Socket(String host, int port, InetAddress localAddr, int localPort)
创建一个套接字并将其连接到指定远程主机上的指定远程端口。- localPort 客户端 端口,port 远程服务器端口
- 连接功能:
public void connect(SocketAddress endpoint) throws IOException
将此套接字连接到服务器
- 绑定功能
public void bind(SocketAddress bindpoint) throws IOException
将此套接字链接到本地地址
- 读写功能
public InputStream getInputStream() throws IOException
返回此套接字的输入流。public OutputStream getOutputStream() throws IOException
返回此套接字的输出流。
- 获取功能
- 本地获取
public int getLocalPort()
获取 端口号,-1表示未指定,使用默认端口。public InetAddress getLocalAddress()
获取 IP 地址的对象public SocketAddress getLocalSocketAddress
获取 套接字地址对象,包括 getLocalPort 和 getLocalAddress 的内容- 远程获取
public int getPort()
获取远程服务器 端口号,-1表示未指定,使用默认端口。public InetAddress getInetAddress()
获取远程 IP 地址的对象public SocketAddress getRomoteSocketAddress
获取远程 套接字地址对象,包括 getPort 和 getInetAddress 的内容
- 关闭功能
public void shutdownInput()
此套接字的输入流置于“流的末尾”。 之后 再访问时,返回 EOF ,可用于结束阻塞,从而停止客户端。public void shutdownOutput()
禁用此套接字的输出流。 再输出时,抛出 IOException 异常。
- 构造器:
多线程服务器
应用多线程实现服务器和多客户端之间的通信
基本步骤:
- 服务器创建 ServerSocket ,循环调用 accept() 监听(
while(true)
) 客户端的连接 - 客户端启动时,创建一个socket 请求和服务器连接
- 服务器接受客户端的连接请求,创建 socket 与 该客户端建立专线连接
- 建立连接的两个 socket 在一个单独的线程上对话
- 服务器端继续等待新的连接
TCP服务器客户端通信原理图解
UDP 编程
简述
进行数据传输时,首先需要将 要传输的 数据定义成 数据报(Datagram),在数据报中指明数据所要到达的 Socket (IP地主和端口号),然后将数据报发送过去。
相关操作类
DatagramPocket 类:表示数据报包
常用方法:
-
构造器:
-
发送方:
DatagramPacket(byte[] buf, int length, InetAddress address, int port)
构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
构造数据报包,用来将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号。DatagramPacket(byte[] buf, int length, SocketAddress address)
构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)
构造数据报包,用来将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号。
-
接收方:
DatagramPacket(byte[] buf, int length)
构造 DatagramPacket,用来接收长度为 length 的数据包。DatagramPacket(byte[] buf, int offset, int length)
构造 DatagramPacket,用来接收长度为 length 的包,在缓冲区中指定了偏移量。
-
-
读写器:
DatagramSocket 类:实现端到端通信
此类表示用来发送和接收数据报包的套接字。
常用方法:
-
远程主机的IP地址和端口号在 数据报中已经传递。
-
构造器:
- 客户端(发送端):
DatagramSocket()
构造数据报套接字并将其绑定到本地主机上任何可用的端口。- 服务器(接收端):
DatagramSocket(int port)
创建数据报套接字并将其绑定到本地主机上的指定端口。DatagramSocket(int port, InetAddress laddr)
创建数据报套接字,将其绑定到指定的本地地址。DatagramSocket(SocketAddress bindaddr)
创建数据报套接字,将其绑定到指定的本地套接字地址。
-
发送:
public void send(DatagramPacket p)
从此套接字接收数据报包。
-
接受:
public void receive(DatagramPacket p)
从此套接字发送数据报包。
接收端(服务器)
- 创建 DatagramSocket,指定端口号
- 创建 DatagramPacket,接受客户端发送的 数据信息
- 读取数据
- 创建 缓冲字节数组,构造 数据报 对象,相应客户端数据信息,需要的IP地址和端口号,通过接受到的数据报获取
- 写会数据
发送端(客户端)
- 定义发送内容
- 创建数据报,包含要发送的内容和远程服务器的IP地址和端口号
- 创建DatagramSocket
- 发送数据
- 创建新的数据报对线
- 接受服务器相应信息
UDP 发送接收图解
总结
重点
- Socket 通信原理
- 基于TCP的Socket通信
经验和技巧
- 多线程优先级
未设置优先级可能会导致运行时速度非常慢,可适量提高优先级。 eg :thread。setPriority=4
(默认优先级是 5)
- 是否关闭输入输出流
对于 同一个Socket
,如果关闭了流,将导致和流相关的Socket
也会关闭,所以一般不关闭 流,直接关闭Socket
对象即可。
- 使用 TCP 通信传输对象
- Socket 编程 创递文件