尚硅谷_Java零基础教程-java入门必备-初学者基从入门到精通全套完整版(宋红康主讲) P620-635
(*)表示仅需了解
文章目录
1. 网络编程概述
- Java是Intenet上的语言,它从语言级上提供了对网络应用程序的支持。
- java提供的网络类库,可以实现无痛的网络连接,联网的底层细节被隐藏在java的本机安装系统里,由JVM进行控制。并且java实现了一个跨平台的网络库,程序员面对的是一个统一的网络编程环境。
- 网络编程的目的:直接或间接地通过网络协议与其他计算机实现数据交换,进行通讯。
- 网络编程中有两个主要问题:
- 如何准确的定位网络上一台或多台主机;定位主机上的特定应用
- 找到主机后如何可靠高效的进行数据传输。
2. 网络通信要素概述
- IP和端口号
- 网络协议
- OSI参考模型:理想化
- TCP/IP模型:
3. 通信要素1:IP和端口号
IP地址
- 分类1:
- IPv4
- IPv6
- 分类2:
- 公网
- 私网
实例化 InetAddress
InetAddress inet1 = InetAddress.getByName("192.168.10.14");
InetAddress inet2 = InetAddress.getByName("hust.edu.cn");
System.out.println(InetAddress.getLocalHost());
端口号
- 分类
- 公认端口:0~1023(如默认的,HTTP80,FTP21,Telnet23)
- 注册端口:1024~49151。分配给用户进程或应用程序。(如默认的,Tomcat8080,MySQL3306,Oracle1521)
- 动态/私有端口:49152~65535
- 端口号与IP地址组合得到一个网络套接字:Socket。
4. 通信要素2:网络通信协议
- 网络通信协议:计算机网络中实现通信必须有一些约定,即通信协议,对速率,传输代码、代码结构、传输控制步骤、出错控制等制定标准。
- 通信协议分层的思想:在制定协议时,把复杂成分分解成一些简单的成分,再把它们复合起来。最常用的复合方式是层次方式,即同层间可以通信,上一层可以调用下一层,而与再下一层不发生关系。各层互不影响,利于系统的开发和扩展。
TCP/IP协议簇
- 传输层协议中有两个非常重要的协议:
- 传输控制协议TCP(Transimission Control Protocol)
- 用户数据报协议UDP(User Datagram Protocol)
- TCP/IP及其两个主要协议:传输控制协议(TCP)和网络互联协议(IP)而得名,实际上是一组协议,包括多个具有不同功能且互为关联的协议。
- IP协议是网络层 的主要协议,支持网间互联的数据通信。
- TCP/IP协议模型从更实用的角度出发,分为:物理链路层、网络层、传输层、应用层
TCP
- 使用 TCP协议前,须建立TCP连接,形成传输数据通道
- 传输前,采用“三次握手”方式,点对点通信,是可靠的。
- TCP协议进行通信的两个应用进程:客户端、服务端
- 在连接中可进行大数据量的传输
- 传输完毕,需释放已建立的连接,效率低
UDP协议
- 将数据、源、目的封装成数据包,不需要建立连接
- 每个数据报的大小限制在64K内
- 发送不管对方是否准备好,接收方收到也不确认,故是不可靠的。
- 可以广播发送
- 发送数据结束无需释放资源,开销小,速度快
5. TCP网络编程
例1:客户端发送数据给服务器端,服务器端接收
服务器端:
- 创建服务器端的ServerSocket ,指明自己的端口号
- 调用accept()表示接收来自客户端的socket
- 获取输入流
- 读取输入流中的数据
try{
InetAddress inet = InetAddress.getByName("127.0.0.1");
try (ServerSocket socket = new ServerSocket(8899);
Socket socket1 = socket.accept();
InputStream is = socket1.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream()){
//接收数据
// byte[] buffer = new byte[20];
// int len;
// while ((len=is.read(buffer))!=-1){
// System.out.println(new String(buffer, 0, len));
// }
//避免出现乱码
byte[] buffer = new byte[20];
int len;
while ((len=is.read(buffer))!=-1){
baos.write(buffer,0,len);
}
System.out.print("From:");
System.out.println(socket1.getInetAddress().getHostAddress());
System.out.println(baos.toString());
}
} catch (IOException e) {
e.printStackTrace();
}
客户端:
- 创建一个Socket 对象,指明服务器端的ip和端口号
- 获取一个输出流,用于输出数据
- 写出数据的操作
- 关闭资源
try{
InetAddress inet = InetAddress.getByName("127.0.0.1");
try (Socket socket = new Socket(inet,8899);
OutputStream os = socket.getOutputStream();){
os.write("hello,我是客户端".getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
例2:客户端发送文件给服务器端,服务器端保存
String curPath = "src\\learn\\others\\io\\";
//客户端
@Test
public void client() {
try{
InetAddress inet = InetAddress.getByName("127.0.0.1");
try (Socket socket = new Socket(inet,8899);
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream(curPath+"杨慎.png")){
os.write(fis.readAllBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
//服务端
@Test
public void server(){
try{
InetAddress inet = InetAddress.getByName("127.0.0.1");
try (ServerSocket socket = new ServerSocket(8899);
Socket socket1 = socket.accept();
InputStream is = socket1.getInputStream();
FileOutputStream fos = new FileOutputStream("save.png");
ByteArrayOutputStream baos = new ByteArrayOutputStream()){
//接收数据
// byte[] buffer = new byte[20];
// int len;
// while ((len=is.read(buffer))!=-1){
// baos.write(buffer,0,len);
// }
System.out.print("From:");
System.out.println(socket1.getInetAddress().getHostAddress());
fos.write(is.readAllBytes());
System.out.println(baos.toString());
}
} catch (IOException e) {
e.printStackTrace();
}
}
例3:客户端发送文件给服务器端,服务器端保存,并返回“发送成功”给客户端,并关闭相应的连接
public class TCPTest3 {
String curPath = "src\\learn\\others\\io\\";
//客户端
@Test
public void client() {
try{
InetAddress inet = InetAddress.getByName("127.0.0.1");
try (Socket socket = new Socket(inet,8899);
// Socket socket2 = new Socket(inet,8900);
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream(curPath+"杨慎.png");
InputStream is = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();){
os.write(fis.readAllBytes());
//非常重要,如果不明确表示停止输出,那服务器端可能一直在等待客户端的输出
// 那就阻塞在这里,无法进行下一步。
socket.shutdownOutput();
baos.write(is.readAllBytes());
System.out.println(baos.toString());
}
} catch (IOException e) {
e.printStackTrace();
}
}
//服务端
@Test
public void server(){
try{
InetAddress inet = InetAddress.getByName("127.0.0.1");
try (ServerSocket ss = new ServerSocket(8899);
Socket socket = ss.accept();
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(new File("static\\img\\save.png"));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 服务器端反馈
OutputStream os = socket.getOutputStream()){
//接收数据
// byte[] buffer = new byte[20];
// int len;
// while ((len=is.read(buffer))!=-1){
// baos.write(buffer,0,len);
// }
System.out.print("From:");
System.out.println(socket.getInetAddress().getHostAddress());
fos.write(is.readAllBytes());
// System.out.println(baos.toString());
os.write("接收成功".getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
6. UDP网络编程
- 类DatagramSocket和DatagramPacket实现了基于UDP协议网络程序
- UDP数据报通过数据报套接字DatagramSocket发送和接收,系统不保证UDP数据报一定能安全送到目的地,也不确定抵达的时间。
- DatagramPacket对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号
- UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接。如同发快递包裹一样。
public class UDPTest {
//发送端
@Test
public void sender(){
try(final DatagramSocket socket = new DatagramSocket();) {
String str = "我是UDP发送的包包";
final byte[] data = str.getBytes();
InetAddress inet = InetAddress.getLocalHost();
final DatagramPacket packet = new DatagramPacket(data, 0, data.length, inet, 9090);
socket.send(packet);
}catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// socket.close();
}
//接收端
@Test
public void receiver(){
try(final DatagramSocket socket = new DatagramSocket(9090);) {
byte[] buffer = new byte[100];
final DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
socket.receive(packet);
System.out.println(new String(packet.getData()));
}catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
7. URL编程
- URL(Uniform Resource Locator) :统一资源定位符,它表示Internet上某一资源的地址。
- 它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。
- 通过URL我们可以访问互联网上的各种网络资源,如最常见的www/ftp站点,浏览器通过解析给定 的URL可以在网络上查找相应的文件或其他资源。
- URL的基础结构由5部分组成:
<传输协议>://<主机名>:<端口号>/<文件名>#片段名?参数列表
- 例如http://192.168.1.100:8080/helloworld/index.jsp?username=shkstart&password=123
- #片段名:即锚点,例如看小说,直接定位到章节。
- 参数列表格式:参数名1=参数值1&参数名2=参数值2……
简单测试:
public class URLTest {
public static void main(String[] args) {
HttpURLConnection connection = null;
try{
final URL url = new URL("http://localhost:8080");
connection = (HttpURLConnection) url.openConnection();
connection.connect();
try(InputStream is = connection.getInputStream();
FileOutputStream fos = new FileOutputStream("static//img//save.png")){
fos.write(is.readAllBytes());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection!=null){
connection.disconnect();
}
}
}
}