复习Java网络编程.NET包&Java面试题Redis哨兵模式&生活记录一个咸鱼大学生三个月的奋进生活022

Posted Aspiriln

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了复习Java网络编程.NET包&Java面试题Redis哨兵模式&生活记录一个咸鱼大学生三个月的奋进生活022相关的知识,希望对你有一定的参考价值。

复习Java网络编程.NET包

在正式开始之前我们先来了解一下什么是网络?
网络: 以某种介质连接各个终端实现资源共享和通信的通信系统

ISO模型/七层协议
这个知识其实在软考的每一科,无论中级还是高级的考试中都属于一个必考的知识点,应该是每个程序员都要记住的知识

这是我之前备战软考时的笔记,要是大家实在觉得难记,就可以背个口诀:巫术忘传会飚鹰(从下往上每一层)

巫:物理层 、术:数据链路层 、忘:网络层 、传:传输层 、会:会话层 、飚:表示层 、鹰:应用层

然后还有个模型也很重要叫 TCP/IP模型
TCP/IP模型 和 ISO模型是相辅相成的,也就是我笔记中右边的图
应用层(3个) 对应着 应用层、表示层、会话层
传输层(1个) 对应着 传输层
网络层(1个) 对应着 网络层
网络接口层(2个) 对应着 数据链路层、物理层

我们这次主要学习传输层和网络层这两个知识,Java的网络编程用的最多的也就是这两层模型

网络层知识

网络层最常见的应用就是IP地址的应用和协议

IP地址根据位数分为 IPV4 和 IPV6
IPV4(现在很多网站常用):0-255.0-255.0-255.0-255
IPV6(解决IPV4不够用的情况):0-255.0-255.0-255.0-255.0-255.0-255

IP地址还分为 静态IP 和 动态IP
动态IP:上网不用IP时就换人,谁用谁上
静态IP:给常驻机器例如服务器一个IP地址

DNS域名地址:就是最常用的网站域名,例如:www.csdn.net

而 IP地址 和 DNS域名地址 也是能相互转换的
例如:www.baidu.com 就是百度的DNS域名地址
然后我们可以通过DOS命令输入指令获取IP地址

ping www.baidu.com

获取到百度的IP地址,如下图:

又或者是到站长之家输入域名查找该域名的IP地址

又因为 IP地址 和 DNS域名地址 是可以相互转换的
所以我们可以通过在浏览器地址栏输入www.baidu.com 或者 14.215.177.39 这两种方法来访问百度

端口:
用于实现程序间的通信
常用的端口有:
Telnet协议 —— 23
简单邮件传输协议 —— 25
文件传输协议 —— 21
超文本传输协议 —— 80

协议:
网络中计算机之间通信的规则
常用的协议有:
超文本传输协议 (HTTP)
文件传输协议 (FTP)
简单邮件传输协议 (SMTP)
网络新闻传输协议 (NNTP)

传输层知识

传输层最常见的应用就是TCP传输和UDP传输

TCP: 双方都不间断交流,安全,稳定的数据流(就像打电话),因为是数据流所以信息都是以字节的形式传递
UDP: 单方面的间断的,不安全不稳定的数据包(就像写信),因为是数据包所以新消息都是以byte数组的形式传递

java.net包

InetAddress类

封装了 IP地址 和 DNS域名

InetAddress实例化时只能用其中的getByName()方法进行实例化:
InetAddress 实例名 = InetAddress.getByName(“IP地址或DNS”);

.getHostName()方法 —— 返回调用的实例的DNS域名

.getHostAddress()方法 —— 返回调用的实例的IP地址


ServerSocket类和Socket类的使用(基于TCP的通讯)

Socket类
Socket可以使一个应用从网络中读取和写入数据,不同计算机上的两个应用可以通过连接发送和接受字节流,就像是两个客户端要通信时进行传输要用的类,所以Socket经常会发起通信,然后通信建立后就是两个Socket在进行传输。
Socket实例化: Socket 实例名 = new Socket(“要通讯的IP地址”, 要通讯的Port值);
Socket类的常用方法:
.getLocalPort()方法 —— 获取自己的Port值
.getPort()方法 —— 获取通讯对方的Port值

ServerSocket类
因为要实现网络传输,所以要实现一个服务器应用,服务器需随时待命,因为不知道客户端什么时候会发来请求,此时,我们就要使用ServerSocket。
ServerSocket与Socket不同,ServerSocket是等待客户端的请求,一旦获得一个连接请求,就创建一个Socket示例来与客户端进行通信,ServerSocket就像是两个终端(Socket)之间通讯的转化操作。
ServerSocket实例化: ServerSocket 实例名 = new ServerSocket(port值); 【这个port值是用于其他终端联系这个ServerSocket的,也就是Socket类实例化时需要输入的Port值,不指定的话系统会给一个随机的port值】
ServerSocket类的常用方法:
.accept()方法 —— 返回跟本类ServerSocket进行通讯的Socket类

常出现的问题:
Connection reset异常(两边任意一个终端异常终止就会报这个错,因为网络通信之中用I/O读取信息,所以经常会报这个错,循环读取的时候加个判断条件跳出循环就可以解决)

例子(用ServerSocket类和Socket类进行网络通信):
Work29_wangluochuanshuTCPSocket【ServerSocket类】//记住要先启动这个ServerSocket类才能接收信息:

package com.javawork29;

// ServerSocket和Socket使用(基于TCP的通讯)
// 这是被通讯的ServerSocket然后再用Socket进行读取显示

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class Work29_wangluochuanshuTCPServerSocket {

	public static void main(String[] args) {
		ServerSocket serverSocket = null;              // ServerSocket就像是TCP通讯中的两个终端通讯之间的转化操作
		
		Socket socket = null;                          // Socket就像两个通讯终端里的一个被通讯的终端
		
		BufferedReader reader = null;
		BufferedWriter writer = null;
		
		try {
			serverSocket = new ServerSocket(8888);     // 实例化:ServerSocket 名 = new ServerSocket(port值);       这个port数是用于其他终端联系这个ServerSocket的,不指定的话系统会给一个随机的port值
			
			socket = serverSocket.accept();            // .accept()方法 返回跟本类ServerSocket进行通讯的Socket类
			
			// 之后是用I/O包对Socket进行数据读取
			reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));          // 先用.getInputStream()方法获取Socket实例的字节,然后InputStreamReader将字节转换为字符,然后再用BufferedReader缓冲流读取(记得因为InputStreamReader和BufferedReader都是处理流所以需要嵌套实例化使用)
			String info = null;
			while(true) {
				info = reader.readLine();
				System.out.println("ServerSocket收到的消息:" + info);
				if("再见!".equals(info)) {
					break;
				}
			}
			
			// 之后是通过I/O包像另一终端进行通讯(原理是刚才获取的跟本类进行通讯的socket对象再将内容通过I/O更改为其他内容,)
			writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
			writer.write("没钱了就告诉老爸!\\n");
			writer.flush();
			writer.write("你努力学好软件开发!\\n");
			writer.flush();
			writer.write("再见!\\n");
			writer.flush();
			
			
			// socket类中的方法
			System.out.println(socket.getLocalPort());        // .getLocalPort()方法 获得自己的Port值      
			System.out.println(socket.getPort());             // .getPort()方法 获得通讯对方的Port值      
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				// 关闭in和out操作
				if(reader != null) {
					reader.close();
					reader = null;
				}
				if(writer != null) {
					writer.close();
					writer = null;
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

Work29_wangluochuanshuTCPSocket【Socket类】:

package com.javawork29;

// ServerSocket和Socket使用(基于TCP的通讯)
// 这是先进行通讯的连接ServerSocket的Socket

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class Work29_wangluochuanshuTCPSocket {

	public static void main(String[] args) {
		
		Socket socket = null;
		
		BufferedWriter writer = null;
		BufferedReader reader = null;
		
		try {
			socket = new Socket("127.0.0.1", 8888);                 // Socket实例化:Socket 名 = new Socket("要通讯的IP地址", 要通讯的Port值);    这就建立通讯了,之后再在这个Socket实例里进行I/O的输写信息
			
			// 通过I/O书写Socket进行传输信息,因为那边readLine方法所以有换行才能读取
			writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
			writer.write("你好,老王!\\n");
			writer.flush();
			writer.write("最近缺钱了!\\n");
			writer.flush();
			writer.write("再打一千!\\n");
			writer.flush();
			writer.write("再见!\\n");
			writer.flush();
			
			// 通过I/O读取Socket进行显示信息
			reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			String info = null;
			while(true) {
				info = reader.readLine();
				System.out.println("Socket收到的信息:" + info);
				if("再见!".equals(info)) {
					break;
				}
			}
			
			// socket类中的方法
			System.out.println(socket.getLocalPort());        // .getLocalPort()方法 获得自己的Port值      
			System.out.println(socket.getPort());             // .getPort()方法 获得通讯对方的Port值  
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				// 关闭in和out操作
				if(reader != null) {
					reader.close();
					reader = null;
				}
				if(writer != null) {
					writer.close();
					writer = null;
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

运行结果【发起通信的Socket类】:

运行结果【接收到通信的ServerSocket类】:


DatagramSocket和DatagramPacket使用(基于UDP的通讯)

DatagramSocket类
DatagramSocket是基于UDP的连接,所以客户端不需要先连接数据,可以直接发送给指定服务端。
DatagramSocket实例化: DatagramSocket 实例名 = DatagramSocket(port值); —— 需要给一个port值以供传输信息
DatagramSocket类的常用方法:
.send()方法 —— 用于发送packet对象
.receive()方法 —— 用于接收packet对象

DatagramPacket类
DatagramPacket就像UDP通信协议中用来建立通讯的两个客户端,当需要发送消息时和接收消息时两个实例化的方法是不一样的。
DatagramPacket实例化:
当需要发送信息时的DatagramPacket:
DatagramPacket 实例名 = new DatagramPacket(pool, pool.length, InetAddress.getByName(“发送的IP地址”), 对方的port值);

当需要接收信息时的DatagramPacket:
DatagramPacket 实例名 = new DatagramPacket(pool, pool.length);

DatagramPacket类的常用方法:
.setData(“内容”.getBytes()) —— 设置packet内容的方法,里面写需要发送内容的byte数组值
.getData() —— 获取packet的内容,接收到的packet对象里面是byte数组,需要用实例化String里的转化byte数组内容的构造方法实例化:String info = new String(packet.getData());

常出现的问题:
因为UDP是通过byte数组进行传播数据的,所以要声明一个byte数组pool,大小为8的倍数

例子(用DatagramSocket类和DatagramPacket类进行网络通信):
Work29_wangluochuanshuUDPDatagram1【发送信息的DatagramPacket类】:

package com.javawork29;

// DatagramSocket和DatagramPacket使用,本类是终端1(基于UDP的通讯)

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class Work29_wangluochuanshuUDPDatagram1 {

	public static void main(String[] args) {
		
		System.out.println("test1开始");
		
		DatagramSocket socket = null;                  // DatagramSocket进行发送信息
		DatagramPacket packet = null;                  // DatagramPacket进行信息编写,根据发送还是接收实例化格式不同
		
		try {
			
			socket = new DatagramSocket(5555);         // 实例化DatagramSocket(port值)时也需要给一个port值以供传输信息
			
			byte[] pool = new byte[1024];              // 因为UDP是通过byte数组进行传播数据的,所以要声明一个byte数组pool,大小为8的倍数
			
			// 实例化发送信息时的DatagramPacket:   DatagramPacket 名 = new DatagramPacket(pool, pool.length, InetAddress.getByName("发送的IP地址"), 对方的port值);
			packet = new DatagramPacket(pool, pool.length, InetAddress.getByName("127.0.0.1"), 6666);
			
			packet.setData("你好test2".getBytes());         // DatagramPacket对象的.setData("内容".getBytes())设置packet内容方法,里面写需要发送内容的byte数组值
			
			socket.send(packet);                            // socket.send(packet);  .send()方法 发送packet对象
		
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

Work29_wangluochuanshuUDPDatagram2【接收信息的DatagramPacket类】//记住要先启动这个接收信息的DatagramPacket类才能接收到信息:

package com.javawork29;

// DatagramSocket和DatagramPacket使用,本类是终端2(基于UDP的通讯)

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.net.UnknownHostException;

public class Work29_wangluochuanshuUDPDatagram2 {

	public static void main(String[] args) {
		
		System.out.println("test2开始");
		
		DatagramSocket socket = null;                  // DatagramSocket进行发送信息
		DatagramPacket packet = null;                  // DatagramPacket进行信息编写,根据发送还是接收实例化格式不同
		
		try {
			
			socket = new DatagramSocket(6666);         // 实例化DatagramSocket(port值)时也需要给一个port值以供传输信息
			
			byte[] pool = new byte[1024];
			
			// 实例化接收信息时的DatagramPacket:   DatagramPacket 名 = new DatagramPacket(pool, pool.length);
			packet = new DatagramPacket(pool, pool.length);
			
			socket.receive(packet);                    // socket.receive(packet);  .receive()方法 接收packet对象
			
			String info = new String(packet.getData());           // 接收到的packet对象里面是byte数组,需要用实例化String里的转化byte数组内容的构造方法实例化
			// DatagramPacket对象的.getData()方法获取packet的内容
			
			System.out.println("test2收到的信息:" + info);
		
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

运行结果【接收信息的DatagramPacket类也就是test2类】:

运行结果【发送信息的DatagramPacket类也就是test1类】:

好了以上就是网络编程所学内容,下次帖子开始我们就要复习第二个项目了,就是根据之前所学的 javaswing、多线程、I/O、网络通信 所做的简易在线聊天系统,敬请期待哦

学习Java面试题(Redis哨兵模式)

指路陈哈哈大佬的Redis相关面试题原帖

照片分享

作者:摄影记录者|张乐   作品名:武汉黄鹤楼夜色  出自500px社区






2021.07.27  by wyh

以上是关于复习Java网络编程.NET包&Java面试题Redis哨兵模式&生活记录一个咸鱼大学生三个月的奋进生活022的主要内容,如果未能解决你的问题,请参考以下文章

列出自己常用的jdk包.

JavaSE复习网络编程

Java面试复习重点:三面腾讯,已拿offer

三年经验Java开发面经总结,附赠复习资料

网络编程2之Socket简介和java.net包

三面阿里(支付宝)Java高开岗,复习两月有幸拿到offer