说起网络,相信大家都不陌生,把分散在不同地点的计算机设备,通过传输介质、通信设施和网络通信协议,实现资源共享和信息传输的系统,我们称之为:计算机网络系统。
计算机网络的最简单的定义是:一些互相连接的、自治的计算机的集合。
互连:是指计算机之间可以通过有线或无线的方式进行数据通信;
自治:是指独立的计算机,他有自己的硬件和软件,可以单独运行使用;
集合:是指至少需要两台计算机;
而网络编程其实就是编写程序使网络上的两个(或多个)设备(如计算机)之间进行数据传输。
为了使两个设备之间能进行数据传输,必须在它们之间建立通信工具(即接口),使彼此之间能进行信息交换,工具包括两部分:
从软件角度看,计算机网络可以分为网络体系结构和网络协议两部分。
通过网络将数据从一台主机发送到另外的主机上,其实是一项非常复杂的操作,必须仔细地协调网络上的物理特性以及所发送数据的逻辑特征。
计算机网络体系结构,其实是计算机网络层次和协议的集合。网络体系结构对计算机网络实现的功能,以及网络协议、层次、接口和服务之间的通信进行了约定描述,但并不涉及具体的实现。
在网络体系结构中,网络设备之间的通信被分解为多个层,每一层只与紧挨其上和其下的层对话,层与层之间用接口连接(接口指的是同一节点内相邻层之间交换信息的连接处,也叫服务访问点)。
通信的双方必须具有相同的层次,层次实现的功能由协议数据单元(PDU)来描述,不同系统中的同一层构成对等层,对等层之间通过对等层协议进行通信,理解彼此定义好的规则和约定。
将网络进行分层,这样即使要修改甚至替换某一层的软件,只要层与层之间的接口保持不变,就不会影响到其他层。
世界上第一个网络体系结构由 IBM 公司提出,之后其他公司也相继提出自己的网络体系结构。为了促进计算机网络的发展,国际标准化组织 ISO 在现有网络的基础上,提出了不基于具体机型、操作系统或公司的网络体系结构,称为开放系统互连参考模型,即 OSI/RM(Open System Interconnection Reference Model)。
OSI 模型把网络通信的工作分为 7 层,分别是应用层、表示层、会话层、传输层、网络层、数据链路层和物理层。
由于 OSI 模型过于庞大、复杂招致了许多批评,与此相对,美国国防部提出了 TCP/IP 参考模型,把网络通信的工作分为 4 层,分别是应用层、传输层、网络层、网络接口层,简化了 OSI 参考模型。
由于 TCP/IP 参考模型的简单,获得了广泛的应用,并成为后续网络通信事实上的标准。
如今用的最多的是TCP/IP体系结构,现今规模最大的、覆盖全球的、基于TCP/IP的互联网并未使用OSI标准。
TCP/IP体系结构相当于将OSI体系结构的物理层和数据链路层合并为了网络接口层,并去掉了会话层和表示层。
TCP/IP在网络层使用的协议是IP协议,IP协议的意思是网际协议,因此TCP/IP体系结构的网络层称为网际层
各个层级职责描述如下:
了解完网络体系结构后,相信我们对网络设备之间的数据传输已经有了初步的认识。计算机之间能够进行相互通信,主要是因为它们都共同遵守一定的规则,就如同人与人之间能相互交流是因为大家使用了共同的语言文字一样,这些规则我们称之为网络协议。
IP 协议的作用在于把各种数据包准备无误的传递给其他设备,其中 IP 地址和 MAC 地址都可以代表设备在网络中的唯一标识。
先说说 IP 地址。
IP 地址又被称为逻辑地址,当设备连接上网络时,由路由器给设备生成一个在当前网络下唯一的 IP 地址。
同时 IP 地址又分为 IPv4 和 IPv6。
11000000 10101000 00000001 01000010
,这么长的地址处理起来太费劲了,为了方便使用,IP 地址被写成十进制的形式,中间使用符号.
分隔不同的字节,因此上面的 IP 地址可以用十进制192.168.1.66
表示,IP 地址的这种表示法叫做点分十进制法
,这显然比 1 和 0 更容易记住。abcd : 1234 : aCA9 : 123 : 4567 : 089 : 0 : 0000
。以windows
系统为例,可以在 DOS 中输入ipconfig
命令获取本机的 IP 地址。
关于 IP 地址的划分,也有讲究!
127.0.0.1
:表示回送地址,也代表本机地址,一般用来测试使用190.168.0.0 – 192.168.255.255
:表示私有地址,属于非注册地址,专门为组织内部使用,也被称为内网地址再来说说设备的 MAC 地址。
MAC 地址也叫物理地址、硬件地址,由网络设备制造商生产时烧录在网卡的 EPROM 上。 MAC 地址的长度为 48 位(6 个字节),通常用 12 个十六进制数来表示,每 2 个十六进制数之间用冒号隔开,如08:00:20:0A:8C:6D
就是一个 MAC 地址,只要不更改自己的 MAC 地址,MAC 地址在全球是唯一的,但是可以肉眼得出结论,它比 IPv4 地址更难记忆。
既然 Mac 地址也具有唯一性,为何不能作为 ip 地址资源呢?
TCP 协议是面向连接的传输层协议,每次连接都需要经过 3 个阶段:连接建立、数据传送和连接释放,即传输数据之前,在发送端和接收端建立逻辑连接、然后传输数据、最后断开连接,它保证了两台计算机之间可靠无差错的数据传输。
下面我们一起来看看 TCP 协议的报文格式,包含了哪些内容!
TCP 报文段包括协议首部和数据两部分,协议首部的固定部分是 20 个字节,头部是固定部分,后面是选项部分。
下面是报文段首部各个字段的含义:
向深入的了解 TCP 原理的同学,可以看看这篇博客文章。
下面我们要重点说说 TCP 中的三次握手与四次挥手,因为这种数据传输模型保证了两台计算机之间可靠无差错的数据传输。
当两个设备之间准备传输时,TCP 会建立连接,创建连接的阶段需要三次握手,过程如下:
- 第一次握手:客户端向服务器端发出连接请求,等待服务器确认
- 第二次握手:服务器端收到请求后,向客户端回送一个确认,通知客户端收到了连接请求
- 第三次握手:客户端再次向服务器端发送确认信息,确认连接
完成以上 3 次握手之后,可靠性连接建立完成,准备进行数据传输。
当数据传输完毕之后,准备释放连接,连接的释放需要四次挥手,过程如下:
- 第一次挥手:客户端向服务器端发出请求切断连接,等待服务器确认
- 第二次挥手:服务器端收到请求后,向客户端回送一个确认信息,并同意关闭请求
- 第三次挥手:服务器端再次向客户端发出请求切断连接,等待客户端确认
- 第四次挥手:客户端收到请求后,向服务器端回送一个确认信息,并同意关闭请求
完成以上 4 次挥手之后,连接释放完成。
UDP 协议是 TCP/IP 协议簇中面向无连接的传输层协议,特点如下:
下面我们一起来看看 UDP 协议的报文格式,包含了哪些内容!
UDP 协议由两部分组成:首部和数据。其中,首部仅有 8 个字节,包括源端口和目的端口、长度(UDP用于数据报的长度)、校验和。
UDP 协议没有像 TCP 协议那样的三次握手、四次挥手操作,数据传输模型非常简单,它只管发和收,总结下来,两者具体的区别如下:
HTTP 协议,也俗称超文本传输协议,它是基于 TCP 协议之上的请求/响应式的应用层协议,使用 TCP/IP 来传输数据,也是互联网上应用最为广泛的一种网络协议。
HTTP 协议同时也是 Web 浏览器和 Web 服务器之间通信的标准协议。HTTP 指定客户端与服务器如何建立连接、客户端如何从服务器请求数据,服务器如何响应请求,以及最后如何关闭连接。
对于从客户端到服务器的每一个请求,都有 4 个步骤:
现在使用的 HTTP 协议是 HTTP/1.1 版本,1997 年之前采用的是 HTTP/1.0 版本,两者区别在于:HTTP 连接在 1.0 版本中采用非持续连接工作方式,1.1 版本采用的是持续连接工作方式。持续连接是指服务器在发送响应后仍然在一段时间内保持这条由 TCP 传输层协议建立起来的连接,使客户端和服务器可以继续在这条连接上传输 HTTP 报文,避免重复的创建连接和释放连接。
是否采用持续连接工作方式,1.0 中默认是关闭的,需要在 HTTP 头加入Connection:Keep-Alive
,才能启用Keep-Alive
。HTTP1.1 中默认启用Keep-Alive
,如果加入Connection:close
,请求完会关闭连接。目前大部分浏览器都是用 HTTP1.1 协议,也就是说默认都会发起Keep-Alive
的连接请求了,是否能完成一个完整的Keep-Alive
连接就看服务器设置情况。
下面我们一起来看看 HTTP 协议的报文格式,HTTP 报文主要包括:请求报文和响应报文两种。
HTTP 请求报文的格式如下:
HTTP 请求报文由请求行、首部行和实体主体组成,由浏览器发送给服务器。上面这张图中 SP 表示空格,cr lf 表示回车和换行。下图是谷歌浏览器内访问服务器查看的 HTTP 请求报文例子:
HTTP 响应报文的格式如下:
上面这张图是 HTTP 响应报文,它由状态行、首部行和实体主体组成。下图是谷歌浏览器内访问服务器查看的 HTTP 响应报文例子:
在上面的 HTTP 请求报文例子中,我们可以看到请求方法是 GET,它表示请求由 URL 所标志的信息,除了 GET,还有其他几种常用的方法。
在 HTTP 响应报文的例子中,我们可以看到状态码是 200,表示响应成功,除此之外,还有其他的状态码,总共 5 大类。
熟悉 HTTP 协议的同学可能都知道,HTTP 协议是以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了 Web 浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此 HTTP 协议不适合传输一些敏感信息,比如信用开号、密码等。
为了解决 HTTP 协议的这一缺陷,需要使用另一种协议:HTTPS 协议。
HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的 HTTP 通道,简单来说就是 HTTP 的安全版。即在 HTTP 下加入 SSL 协议,SSL 依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。
HTTPS 和 HTTP 的区别主要为以下三点:
更多的网络协议介绍,有兴趣的朋友可以看看这篇博客文章。
看完以上信息之后,要想让网络中的计算机能够互相通信,少不了以下三个核心要素:
0 - 65535
Java 语言对网络编程提供了良好的支持,通过其提供的接口我们可以很方便地进行网络编程。
下面我们一起来看看相关的代码实例!
URL 表示统一资源定位符,指向万维网上“资源”的指针。
一个标准的 URL 包括以下几个部分:
在 www 上,每一信息资源都有统一且唯一的地址。
代码实例如下:
public static void main(String[] args) throws MalformedURLException {
URL url = new URL("http://www.baidu.com:80/index.html?uname=dream&age=18#a");
// 获取四个值:协议、域名、端口、请求资源
System.out.println("协议:" + url.getProtocol());
System.out.println("域名|IP:" + url.getHost());
System.out.println("端口:" + url.getHost());
System.out.println("请求资源:" + url.getPath());
// 参数
System.out.println("参数:" + url.getQuery());
// 锚点
System.out.println("锚点:" + url.getRef());
}
输出结果:
协议:http
域名|IP:www.baidu.com
端口:www.baidu.com
请求资源:/index.html
参数:uname=dream&age=18
锚点:a
为了方便我们对 IP 地址的获取和操作,Java 提供了一个类InetAddress
供我们使用。
代码实例如下:
public static void main(String[] args) throws UnknownHostException {
InetAddress address = InetAddress.getByName("www.baidu.com");
System.out.println("主机名:" + address.getHostName());
System.out.println("IP地址: " + address.getHostAddress());
}
输出结果:
主机名:www.baidu.com
IP地址: 14.119.104.254
IntetSocketAddress 包含 IP 和端口信息,常用于 Socket 通信。此类实现 IP 套接字地址(IP 地址+端口号),不依赖任何协议。
代码实例如下:
public static void main(String[] args) {
// 指定ip、端口
InetSocketAddress socketAddress = new InetSocketAddress("14.119.104.254",80);
System.out.println("主机名:" + socketAddress.getHostName());
System.out.println("地址:" + socketAddress.getAddress());
System.out.println("端口号:" + socketAddress.getPort());
System.out.println("==================================");
// 指定主机名、端口
InetSocketAddress socketAddress2 = new InetSocketAddress("www.baidu.com",80);
System.out.println("主机名:" + socketAddress2.getHostName());
System.out.println("地址:" + socketAddress2.getAddress());
System.out.println("端口号:" + socketAddress2.getPort());
}
输出结果:
主机名:14.119.104.254
地址:14.119.104.254/14.119.104.254
端口号:80
==================================
主机名:www.baidu.com
地址:www.baidu.com/14.119.104.254
端口号:80
Java 的网络编程主要涉及到的内容就是 Socket 编程。
Socket,也被称为套接字,它是网络通信中两台主机之间逻辑连接的端点的抽象表示,包含了进行网络通信必须的五种信息:连接使用的协议、本地主机的 IP 地址、本地进程的协议端口、远程主机的 IP 地址、远程进程的协议端口。
实际上,Socket 是对 TCP/IP 协议的封装实现,Socket 本身并不是协议,而是一个可以调用的接口(API);通过 Socket,程序员可以更方便地使用 TCP/IP 协议栈里面的逻辑,比如 create、accept、send、read 和 write 等等。
关于 Socket 和 TCP/IP 协议关系,如果感觉很抽象,你可以这样理解。TCP/IP 协议栈是网络信息传输的一个运行机制方案,而 Socket 是 TCP/IP 协议栈的具体技术编程实现。
Socket 编程主要涉及到客户端和服务端两个方面,以 TCP 协议通信为例,首先是在服务器端创建一个服务器套接字(ServerSocket),并把它附加到一个端口上,服务器从这个端口监听连接。端口号的范围是 0 到 65536,但是 0 到 1024 是为特权服务保留的端口号,在指定端口时尽量避开这个区间,我们可以选择一个当前没有被其他进程使用的端口。
客户端请求与服务器进行连接的时候,根据服务器的域名或者 IP 地址,加上端口号,打开一个 Socket 套接字。当服务器接受连接后,服务器和客户端之间的通信就可以像输入输出流一样进行操作。
Socket 通信模式图
下面我们一起来看看具体的代码示例,更容易理解。
TCP 协议可以保证数据可靠、安全的传输给另一台主机,实际应用非常广泛,下面我们一起来看看如何实践。
首先创建一个服务端,代码实例如下:
public class ServerAdminTest {
public static void main(String[] args) throws IOException {
//使用需要捕获异常,因为可能会存在无法连接的情况
ServerSocket serverSocket = new ServerSocket(8080);
//测试语句
System.out.println("本地服务器已开启");
while (true){
try {
//等待客户端的连接
Socket socket = serverSocket.accept();
System.out.println("已收到客户机请求");
//输入流,读取数据用的
InputStream inputStream = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
//读取客户机发送来的消息,设置判断,只有客户机有发送消息才做输出语句
String info;
while((info = reader.readLine()) != null) {
System.out.println("收到客户机消息:"+info);
}
//输出流,发送数据用的
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream);
//给客户机发送一段消息
printWriter.write("hello,我是服务端,已收到你的信息!");
printWriter.flush();
//关闭输入、输出流
reader.close();
printWriter.close();
//最后关闭网络连接
socket.close();
} catch (Exception e){
e.printStackTrace();
}
}
}
}
然后创建一个客户端,代码实例如下:
public class ClientAdminTest {
public static void main(String[] args) throws IOException {
//连接到目标服务器
Socket client = new Socket("127.0.0.1",8080);
System.out.println("客户机已经与服务器建立链接");
//创建输出流
OutputStream outputStream = client.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream);
//输出这段话
printWriter.write("hello,我是客户机!");
printWriter.flush();
//关闭输出,不再输出更多数据,如果不关闭,就会出现服务器无法判断客户机何时会结束发送消息,从而无法进行回应。就像一个人和你打电话的时候一直在说话,你无法在这段时间如回复他。
client.shutdownOutput();
//创建输入流
InputStream inputStream = client.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
//读取服务端发送过来的消息
String info;
while((info = reader.readLine()) != null) {
System.out.println("接受服务器发送的消息:"+info);
}
//关闭输入、输出流
reader.close();
printWriter.close();
//最后关闭网络连接,就和打完电话之后要挂断电话一样
client.close();
}
}
最后依次先后启动服务端、客户端,看看控制台输出结果如何。
服务端输出内容如下:
本地服务器已开启
已收到客户机请求
收到客户机消息:hello,我是客户机!
客户端输出内容如下:
客户机已经与服务器建立链接
接受服务器发送的消息:hello,我是服务端,已收到你的信息!
Socket 对 TCP/IP 协议里面的创建连接、释放连接进行了隐藏,开发者只需要关注数据传输即可。
UDP 协议是一种不可靠的网络协议,它在通信的两端各建立一个 Socket 对象,但是这两个 Socket 只是发送、接收数据的对象,没有客户端和服务器概念。
尽管如此,但是它传输速度高效,实际应用也非常广,下面我们一起来看看如何实践。
首先创建一个接受端,代码实例如下:
public class UDPReceive {
public static void main(String[] args) throws IOException {
System.out.println("接收方启动中...");
// 1、创建接收端的Socket对象(DatagramSocket)
DatagramSocket ds = new DatagramSocket(9999);
// 2、创建一个数据包,用于接收数据
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, 0, bys.length);
// 3、调用DatagramSocket对象的方法接收数据
ds.receive(dp);
// 4、解析数据包,并把数据在控制台显示
System.out.println("数据是:" + new String(dp.getData(), 0, dp.getLength()));
// 5、关闭接收端,释放资源
ds.close();
}
}
然后创建一个发送端,代码实例如下:
public class UDPSend {
public static void main(String[] args) throws Exception {
System.out.println("发送方启动中...");
// 1、使用DatagramSocket指定端口,创建发送端
DatagramSocket client = new DatagramSocket(8888);
// 2、准备数据,一定要转成字节数组
String data = "Java YYDS";
// 3、封装成DatagramPacket包裹,需要指定目的地(IP+port)
byte[] bys = data.getBytes();
DatagramPacket packet = new DatagramPacket(bys, 0, bys.length, new InetSocketAddress("127.0.0.1", 9999));
// 4、发送包裹 void send(DatagramPacket p)
client.send(packet);
// 5、释放资源
client.close();
}
}
最后依次先后启动接受端、发送端,看看控制台输出结果如何。
接受端输出内容如下:
接收方启动中...
数据是:Java YYDS
更多关于计算机网络学习查询相关资料如
计算机网络整理笔记 - 专题 - 简书