1.网络编程基础
网络资源
为什么需要网络编程? ------丰富网络资源
用户在浏览器中打开在线视频网站,实质是通过网络,获取到网络上的一个视频资源
与打开本地视频文件类似,只是视频文件这个资源来自于网络
网络资源就是在网络中可以获取的各种数据资源,而所有的网络资源都是通过网络编程来进行数据传输的
什么是网络编程
网络编程指网络上的主机,通过不同的进程,以编程的方法实现网络通信(或称为网络数据传输)
只要满足进程不同就行,所以几遍是在同一个主机,只要是不同的进程,基于网络来传输数据也属于网络编程
但是目的是提供网络上的不同主机,基于网络来传输数据资源
网络编程中的基本概念
发送端和接受端
再一次网络数据的传输中:
发送端:数据的发送方进程,称为发送端。发送端主机即网络通信中的源主机
接收端:数据的接收方进程,称为接收端。接收端主机即网络通信中的目睹主机
收发端:发送端和接收端两端,也简称为收发端
注意:发送端和接受端只是相对的,只是一次网络数据传输产生数据流向后的概念

请求和响应
一般来说,获取一个网络资源,涉及到两次网络数据传输:
第一次:请求数据的发送
第二次:响应数据的发送
客户端和服务端
客户端:在常见的网络数据传输的场景下,把提供服务的一方进程,称为服务端,可以提供对外服务
客户端:获取服务的一方进程,称为客户端
常见的客户端服务端模型
最常见的场景,客户端是指给客户使用的程序,服务端是提供用户服务的程序:
1.客户端发送请求到服务端
2.服务端根据请求数据,执行相应的业务处理
3.服务端返回响应:发送业务处理结果
4.客户端根据响应数据,展示处理结果
2.SocKet套接字
概念
SocKet套接字,是有系统提供用于网络通信的计数,是基于TCP/IP协议的网络通信的基本操作单元,基于SocKet套接字的网络程序开发是网路编程
操作系统提供的一组api
分类
传输层两大核心协议
TCP(流套接字)、UDP(数据报套接字),差别非常大
TCP:有连接、可靠传输、面向字节流、全双工
UDP:无连接、不可靠传输、面向数据报、双全工
有连接/无连接(抽象的概念,虚拟的/逻辑上的连接)
要进行网络通信,物理上的连接
对于TCP来说,TCP协议中保存了对端的信息,A和B通信,A和B先建立连接
对于UDP来说,UDP协议本身不保存对方的信息,就是无连接
可靠传输/不可靠传输
网络上数据是非常容易出现丢失的(丢包),光信号/电信号都可能受到外界的干扰(本来传输的是),其中有些bit位就被篡改了,这样乱了的数据会被识别出来,把这样的数据丢掉
网络世界是通过路由器/交换机来连接(类似于十字路口)某个时间段你实际需要转发的数据超过了设备能转发的上限,不能指望一个数据包发送之后100%到达对方
可靠传输的意思不是保证数据包100%到达,而是尽可能的提高传输成功的概率,如果出现丢包了,能够感知到
不可靠传输只是把数据发了就不管了
面向字节流/面向数据报
面向字节流,读写数据的时候是以字节为单位 支持任意长度 =》粘包问题
面向数据报,读写数据的时候,以一个数据报为单位(不是字符) 一次必须读写一个UDP数据报,不能是半个 长度有限制 =》不存在粘包
全双工/半双工
全双工:一个通信链路,支持双向通信 (能读也能写)
半双工:一个通信链路,只支持单向通信(要么读,要么写)
java数据报表套接字通信模型
对于UDP协议来说,具有无连接,面向数据报的特征,即每次都是没有建立连接,并且⼀次发送全部 数据报,一次接收全部的数据报。
DatagramSocket
网卡 =》socket文件,操作网卡的时候,流程和操作普通文件差不多,打开、读写、关闭
操作网课的时候不好直接操作,把操作网卡转换成socket文件,socket文件就相当于"网卡遥控器"
构造方法:
|-------------------------|----------------------------------------------|
| 方法签名 | 方法说明 |
| DatagramSocket() | 创建一个UDP数据报套接字的SocKet,绑定到本机的任意一个随机端口(一般用于客户端) |
| DatagramSocket(int pot) | 创建一个UDP数据报套接字的SocKet,绑定到本机指定的端口(一般用于服务端) |
方法:

DatagramPacket
是UDP SocKet发送和接受的数据报
构造方法:

方法:


InetSocketAddress
构造UDP发送的数据报时,需要传⼊ SocketAddress ,该对象可以使⽤ InetSocketAddress 来创建

代码演示
服务端
对于服务器来说,客户端什么时候发送请求,发多少个请求是无法预测的,因此度武器中通常都有一个死循环,持续不断地尝试读取客户端的请求数据

使用之前先构造空的(不是null),把对象传递到receive里面,receive就会把数据从网卡读出来填充到参数中



socket不用close吗?
文件是否要关闭,要考虑清楚文件对象的生命周期是怎么样的
此处的socket对象,伴随整个UPD服务器,自始至终
如果服务器关闭(进程结束),进程结束时就会自动释放PCB的文件描述表的所有资源,也就不需要手动调用close了
当前服务器启动之后,客户端还没有创建,当然也没有请求发来,在客户端请求发来之前,服务器里面的逻辑都在干嘛

receive会触发阻塞行为,客户端请求发来了,receive才会返回,客户端请求没有发来,receive就会一直阻塞
客户端




127.0.0.1是特殊的IP,表示当前的主机,无论主机的真实IP是啥,都可以使用127.0.0.1代替,类似于this


客户端个服务器都在同一个主机上,是否联网都是可以的,不同主机上必须联网
跨主机通信是更希望看到的结果
拓展

java流套接字通信模型
ServerSocket
Server是创建TCP服务端Socket的api
构造方法:

方法:

Socket
Socket是客户端的Socket,或服务端接收到客户端建立连接(accept方法)的请求后,返回的服务端Socket
不管是客户端还是服务端Socket,都是双方建立练习后,保存对端信息,及用来与对方收发数据的
构造方法:

方法:

代码示例


分工行动

用flush方法来"冲刷缓冲区"



记得要关闭

多线程的诞生就是为这个场景服务
对于频繁的创建和销毁线程可以使用线程池来优化
服务端


客户端


