🎺1. 为什么需要网络编程?
用户在浏览器中,打开在线视频网站,如优酷看视频,实质是通过网络,获取到网络上的一个视频资源。
与本地打开视频文件类似,只是视频文件这个资源的来源是网络。
相比本地资源来说,网络提供了更为丰富的网络资源:
所谓的网络资源,其实就是在网络中可以获取的各种数据资源。
而所有的网络资源,都是通过网络编程来进行数据传输的。
🎷2. 什么是网络编程
网络编程,指网络上的主机,通过不同的进程,以编程的方式实现网络通信(或称为网络数据传输)。
当然,我们只要满足进程不同就行;所以即便是同一个主机,只要是不同进程,基于网络来传输数据,也属于网络编程。
特殊的,对于开发来说,在条件有限的情况下,一般也都是在一个主机中运行多个进程来完成网络编程。
但是,我们一定要明确,我们的目的是提供网络上不同主机,基于网络来传输数据资源:
- 进程A:编程来获取网络资源
- 进程B:编程来提供网络资源
🎸3. 网络编程中的基础概念
- 网络编程:写代码,实现两个 / 多个进程,通过网络,来进行相互通信。
由于进程具有隔离性(每个进程都有自己独立的虚拟空间地址),进程间通信,借助一个每个进程都能访问到的公共区域,完成数据交换。
网络编程,也就是一种进程间通信的方式,借助公共的区域,就是网卡(当下最主流的方式,既能让同一个主机的多个进程间通信,也可以让不同主机的多个进程间通信),尤其是对于高并发,分布式,大数据这样的时代有影响。
- 客户端(client) / 服务器(server)
客户端:主动发送网络数据的一方
服务器:被动接受网络数据的一方
因为服务器无法知道客户端啥时候发来数据,因此就只能长时间运行,甚至 7 * 24 小时运行。
- 请求(request) / 响应(response)
请求:客户端给服务器发送的数据
响应:服务器给客户端返回的数据
- 客户端和服务器之间的交互方式
- 一问一答(最常见的方式,比如浏览网页)
客户端给服务器发个请求,服务器给客户端返回个响应
- 多问一答(更少见一些,比如上传文件)
客户端发多个请求,服务器响应一个
- 一问多答(还行,比如下载文件)
客户端发一个请求,服务器返回多个响应
- 多问多答(远程控制,游戏串流…)
客户端发送多个请求,服务器返回多个响应
进行网络编程,需要使用 操作系统 提供的 网络编程 API
网络编程在应用层进行,就需要调用传输层,正是这个传输层,提供了 “网络通信 api” ,这些 api 也叫做 socket api 。(操作系统提供的原生 api ,是 C 语言的。JVM 非常贴心把 C 风格的 api 封装了一下,变成 Java 中的面向对象风格的 api)
Socket套接字,是由系统提供用于网络通信的技术,是基于TCP/IP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程。
传输层提供了两个非常重要的协议:TCP / UDP。他们截然不同,这两个协议对应的 socket api 也是截然不同的。
流套接字:使用传输层TCP协议
TCP,即Transmission Control Protocol(传输控制协议),传输层协议。
以下为TCP的特点(细节后续再讲):
- 有连接
- 可靠传输
- 面向字节流
- 全双工
对于字节流来说,可以简单的理解为,传输数据是基于IO流,流式数据的特征就是在IO流没有关闭的情况下,是无边界的数据,可以多次发送,也可以分开多次接收。
数据报套接字:使用传输层UDP协议
UDP,即User Datagram Protocol(用户数据报协议),传输层协议。
以下为UDP的特点(细节后续再讲):
- 无连接
- 不可靠传输
- 面向数据报
- 全双工
对于数据报来说,可以简单的理解为,传输数据是一块一块的,发送一块数据假如100个字节,必须一次发送,接收也必须一次接收100个字节,而不能分100次,每次接收1个字节。
原始套接字(了解即可):
原始套接字用于自定义传输层协议,用于读写内核没有处理的IP协议数据。
- 有连接:打电话,先建立连接,然后再通信
- 无连接:发微信,不必建立连接,直接通信即可
- 可靠传输:数据对方收没收到,发送方能够有感知(打电话)
- 不可靠传输:数据对方收没收到,也不管,也不知道(发微信)
网络通信是无法保证 100% 到达的(网线被挖掘机挖断)
- 面向字节流:这里的字节流和文件那里的字节流是一样的(不光概念一样,连代码编写都是一样的)
- 面向数据报:以数据报为传输的基本单位
- 全双工:双向通信,一个管道,能 A->B,B->A 同时进行
- 半双工:单向通信,一个管道,同一时刻,要么 A->B,要么 B->A ,不能同时进行。
- 客户端和服务端:开发时,经常是基于一个主机开启两个进程作为客户端和服务端,但真实的场景,一般都是不同主机。
- 注意目的IP和目的端口号,标识了一次数据传输时要发送数据的终点主机和进程
- Socket编程我们是使用流套接字和数据报套接字,基于传输层的TCP或UDP协议,但应用层协议,也需要考虑,这块我们在后续来说明如何设计应用层协议。
- 关于端口被占用的问题
如果一个进程A已经绑定了一个端口,再启动一个进程B绑定该端口,就会报错,这种情况也叫端
口被占用。对于java进程来说,端口被占用的常见报错信息如下:
此时需要检查进程B绑定的是哪个端口,再查看该端口被哪个进程占用。以下为通过端口号查进程
的方式:
-
在cmd输入 netstat -ano | findstr 端口号 ,则可以显示对应进程的pid。
-
在任务管理器中,通过pid查找进程
解决端口被占用的问题:
- 如果占用端口的进程A不需要运行,就可以关闭A后,再启动需要绑定该端口的进程B
- 如果需要运行A进程,则可以修改进程B的绑定端口,换为其他没有使用的端口。
来源地址:https://blog.csdn.net/m0_67660672/article/details/130079665