目录
JAVA中的网路编程

#JAVA中的网路编程

这篇文章,是关于JAVA网络编程扯蛋,如果蛋疼了呢?就继续往下看吧!

网络模型

关于java的网络编程,其实也没什么的,第一个先扯淡的是这个网络模型:OSI参考模型&TCP/IP参考模型,结构如下图所示:

OSITCPIP参考模型.png

通常来讲,这个做开发的在这个传输层和网际层混,而应用层则是FTP/HTTP协议等,传输层就是这个TCP或者这个UDP啦,这个经常问到,面试的时候,说什么TCP和UDP的区别?不过你看完这篇文章,基本上可以扯淡出来了,嘻嘻!还有网际层就是这个IP啦,最后一个是硬件,网卡之类的。

图片1.png

用户在这个应用层混,我们在这个传输层和网际层混。那么,用户在操作数据时,是怎么样的过程呢?

其实呀,数据先是从用户混的应用层向下封装打包,再经过网络传输到接收端,接收端自下而上拆包,最后得到用户发送的数据。

大概是这样一个模式:A——->B——->B——–>A

上图解释,大家掌声欢迎!

图片2.png

网络通信的三要素

IP地址,端口,还有传输协议

首先是IP地址,这个嘛,其实大家都听得多啦!其实它是一个网络设备标识,就像你家的地址一样,只是,它用数字表示,或者说像门号一样。假如把酒店看成网络,那么每间房门号就是一个IP地址啦。看看它的英文吧,Internet Protocol,也就是网络协议的意思,嘻嘻!理解就好,不解释太多,要不更糊涂了,相信大家都知道IP是什么的。

说到IP,还要说到域名。因为IP纯数字,不好记忆,那么就用域名与之对应,这个呢DNS服务器解决,域名与IP地址是映射关系。比如说,我们可以通过百度的IP地址来找到百度的网页:202.108.22.5 ,也可以通过www.baidu.com来找到同样的页面,这里百度公司就是通过DNS服务器把域名www.baidu.com解析到202.108.22.5,所以他们存在映射关系,这样的话,是不是网民记www.baidu.com比记202.108.22.5这个好多啦!下面请看一下广告:本网站的域名是www.sunofbeach.net,哈哈!

还有就是特殊的IP地址啦:本地的IP地址,或者说是本地的回环地址:127.0.0.1,主机名是:localHost

你也可以打开这个DOC命令行,输入ipconfig查看网络配置。

知道了IP地址,那在JAVA中如何获取IP地址呢?其实很简单,在JAVA中IP地址对应的是:InetAddress类,在java.net包中放着,需要用的话,就不用客气地把它导入。

InetAddress这个类不有构造方法,所以呢,不能实例化,但可以通过它本身的方法获取到对象,还记得单例设计模式也是这样吗?

好,看看主要的方法:

图片3.png

由上面的表子可以看出,这个要获取到IP地址,首先要得到这个InetAddress,然后,通过这个InetAddress对象的getHostAddress方法,就可以获取到这个IP地址。

有些东西要另外说一下,这样方便记忆和理解:

get:获得, Host:主机,Address:地址,也就是获取主机地址的意思,这样你永远记得这个是获取主机IP地址啦,是吧!

那么,如何获取这个InetAddress对象呢?从上面的表子也可以看出有好几个静态的方法呢!这里的前提是我们不知道这个IP地址,要获取的是IP地址,所以我们用这个方法来获取InetAddress对象吧,然后通过getHostAddress()方法来获取IP地址!

图片4.png

代码体现如下:

java
复制代码
//导包
import java.net.*;

public class Demo{
	public static void main(String[] args)throws Exception{
		
		//获取InetAddress对象
		InetAddress ia = InetAddress.getByName("www.sunofbeach.net");
		//然后调用InetAddress对象中的getHostAddress()方法获得IP
		String ip = ia.getHostAddress();
		//输出到控制台上看看结果吧:
		System.out.println("www.sunofbeach.net的IP地址是:"+ip);
	}
}

再来一个获取本地的IP地址试试吧,嘻嘻!

java
复制代码
//导包
import java.net.*;

public class Demo{
	public static void main(String[] args)throws Exception{
		
		//获取InetAddress对象
		InetAddress ia = InetAddress.getLocalHost();
		
		//获取IP地址
		String ip = ia.getHostAddress();
		//在实际开发中,一般简写为:
                //InetAddress ia = InetAddress.getLocalHost().getHostAddress();
		
		System.out.println("本机IP地址为:"+ip);
	}
}

OK,搞定完IP之后,就到这个端口吧!

我们通过IP找到了主机,对吧!但是,但是这个主机上有很多的软件吧,他们都在运行,当我们发送一个数据到主机上,那这个数据到底是给那个软件的呢,这样就出现问题了!解决这个问题,当然是用端口啦,这个端口呢,并不是物理端口,所谓的物理端口就是计算机硬件上的插口。这里的端口是逻辑端口,关于端口的几点说明如下:

1、端口的范围从0~65535(2的16次方减1)

2、系统保留端口为:0~1024

3、一些常用的端口,FTP:21,SMTP:25,HTTP:80,嘻嘻还有好些呢,这些不需要记的,了解一下,吹牛扯淡用得上!

好吧,端口到这里就完事啦,最后一个是:协议!

顾名思义,协议就是一起商量好,共同来往的相关规定,或者说是传输规则。传输协议,UDP和TCP协议。

重点来啦,面试常问哦!UDP和TCP传输协议的区别,下面分别说说哈!

20191018_212759.png

好啦,有了上面两个表子,大家可以对比啦,面试的时候也要会吹牛啦!其实呀,面试官录取你,或者说给你打高分并不是因为你的能力有多好,而是因为你能让他心情愉快,感觉良好就可以了!这是心理学家进行大量实验得出的结果。

对了,上面的三次握手解释一下吧:

Client说:服务端哥,我想联你,在吗?—————>请求链接

Server说:客户端弟,我在的,你联过来吧!———->服务端确认链接

Client说:那好,我真的联上来啦!——————–>客户端确认链接

计算机与计算机之间的通信步骤:

1、通过IP地址找到主机;2、通过端口找到接收的程序;3、通过协议发送数据。

PS:凌晨三点四十分了,电脑没早了,嘻嘻!下次再写吧!晚安!

传输协议:UDP

好啦,我又回来了!继续吧,哈哈!

先说这个UDP,TCP后面说。复习一下吧,UDP,不面向链接,不可靠,速度快,一般用于聊天,视频,通话之类的一次性数据传输,不需要精确数据或者永久数据的情况下使用。

在说这两个传输协议之前,要提到的是Socket,Socket大概是插座的意思,那么这里呢可以理解为网线插口,也就是一个端点。很多资料上也跟语文老师那样形象生动地比喻成港口码头。

现在有两台主机,之间要传输数据,所以呢,首先要有码头,那我们看看如何创建码头。

UDP的码头是DatagramSocket,它可以接受和发送数据“包”。一般发送的话要指定IP地址,还有端口,而接受端可以不指定IP,但要监视端口。下面是DatagramSocket的常用构造方法:

DatagramSocket()
构造数据报套接字并将其绑定到本地主机上任何可用的端口。
DatagramSocket(int port)
创建数据报套接字并将其绑定到本地主机上的指定端口。
DatagramSocket(int port, InetAddress laddr)
创建数据报套接字,将其绑定到指定的本地地址。

第一个一般用于接收端,第二个用于发送端。

方法有那些常用的呢:

20191018_212938.png

主要用到的还是接收和发送,另外就是获取IP地址。

有了这些,我们还需要一个类DatagramPacket,这个类呢,是用于把数据打包的。常用的构造方法列一下:

20191018_213001.png

看起来又长又臭,其实写多几次就很熟悉了,闭着眼睛你都能写出来。

有了码头,有了数据包,接下来就是形象生动地说说步骤:

发送端的操作:

1、建立Socket服务,随便你指不指定端口,不指定系统分配。另外就是端口顺延,如果这次端口是1555,下次就是1556,因为当你运行完程序后,不能保证端口也释放了,为了防止出错,所以就这样顺延下去咯!

2、将要发送的数据封装到包中,准备发送,嘻嘻!

3、当然是发送数据啦,嘻嘻。通过send方法发送出去!管它有没有收到呢!

4、最后,不要忘记关闭资源!

图片21.png

实干兴邦,空谈误国,代码体现一下吧,这个是发送端的哦:

java
复制代码
//发送端

//导包
import java.net.*;

public class Demo{
	public static void main(String[] args)throws Exception{
		
		//创建Socket服务
		DatagramSocket ds = new DatagramSocket();
                //不指定端口也行,稍后在数据里指定。
		
		//把数据打包
		String data = "阳光沙滩:sunofbeaches.com";
		byte[] buf = data.getBytes();
                //把数据转换成字节数组
		DatagramPacket dp = new DatagramPacket(buf,
                                  buf.length,
                                  InetAddress.getByName("PresidentsPC"),
                                  10000);//通过名字获取IP,并指定端口
		
		//发送数据
		ds.send(dp);
		//关闭资源
		ds.close();
	}
}

接受端这边的步骤又是怎么样的呢?差不了多少!

1、建立服务

2、定义一个缓冲区来接受数据

3、调用DatagramPacket中的各种方法来达到我们的需求

4、关闭资源

好,太棒了,接下来还需要接收端的代码:

java
复制代码
//接收端

//导包
import java.net.*;

public class Server{
	public static void main(String[] args)throws Exception{
		
		//建立服务监视这个端口
		DatagramSocket ds = new DatagramSocket(10000);
		
		//定义一个缓冲区用于接收数据
		byte[] buf = new byte[1024];//可以乘以64,因为一个包在64K以内。
		DatagramPacket dp = new DatagramPacket(buf,buf.length);
		ds.receive(dp);
		
		//获取IP,这是一个习惯,因为要知道这数据是从那里来的
		String ip = dp.getAddress().getHostAddress();
		System.out.println("来自"+ip+"的数据是");
		
		//把数据弄出来吧
		System.out.println(new String(buf,0,dp.getLength()));
		
		//关闭资源
		ds.close();		
	}
}

爽吧,这下叼了。来几个例子吧,这些例子都是很经典的。第一个是发送从键盘录入的字符,有了这个基础之后,我们还可以做一个模仿聊天器的程序。

先是发送键盘录入的程序,下面分析一下吧:

1、首先,要建立服务

2、获取资源,从控制台中获取,这个可以用高效的方法BufferedReader,读一行,爽到爆了。

3、把资源打成包发送出去

4、关闭资源。

PS,这次我们进行异常处理,完整地写出代码吧,OK!当然OK,嘻嘻!

第一个是发送端(我们叫客户端吧!(^_^))

java
复制代码
//客户端,用来发送从键盘录入的资源

//导包
import java.net.*;
import java.io.*;

public class Demo{
	public static void main(String[] args){
		
		//建立服务
		DatagramSocket ds = null;
		
		//获取输入字符
		BufferedReader br = null;
		try{
		if(ds==null)
			ds =  new DatagramSocket();
		if(br==null)
			br = new BufferedReader(new InputStreamReader(System.in));//获取键盘录入信息
			
			//把读取的资源打包
			byte[] buf = br.readLine().getBytes();//合在一起写啦。
			
			DatagramPacket dp = 
                        new DatagramPacket(buf,buf.length,
                        InetAddress.getByName("PresidentsPC"),
                        10004);// 打包数据并指定IP和端口
			
			//发送出去
			ds.send(dp);
		}catch(Exception e){
			System.out.println("数据发送失败");
		}finally{
			//关闭资源
			
			ds.close();
			if(br!=null)
			try{
				br.close();
			}catch(Exception e){
				System.out.println("流关不了,坏了!");
			}
		}
	}
}

接下来是接收端(我们叫服务端吧,高端大气上档次)

java
复制代码
//接收端

//导包
import java.net.*;

public class Server{
	public static void main(String[] args){
		
		//创建服务
		DatagramSocket ds = null;
		DatagramPacket dp = null;
		try{
			if(ds==null)
				ds = new DatagramSocket(10004);
			//创建缓冲区
			byte[] buf  = new byte[1024];
			
			//接收数据
			if(dp==null)
				dp = new DatagramPacket(buf,buf.length);
			ds.receive(dp);
			
			String ip  = dp.getAddress().getHostName();
			
			//输出数据到控制台上
			System.out.println(ip+" :"+new String(buf,
                                     0,
                                     dp.getLength()));
			//关闭资源
		
		}catch(Exception e){
			System.out.println("哎呀,妈呀,出问题了!");
		}finally{
			ds.close();
		}		
	}
}

结果是可以的,不过,只不过,呵呵,太不爽了,才玩了一次,接下来,我们要写一个多线程的,不断地接收数据,OK!当然OK!

截图01.png

java
复制代码
// 导包
import java.io.*;
import java.net.*;

public class ChatDemo {

	public static void main(String[] args) {
		
		//创建读取线程
		new Thread(new ChatThread()).start();

		// 创建服务
		DatagramSocket ds = null;
		BufferedReader br = null;
		try {
			if (ds == null)
				ds = new DatagramSocket();
			// 读取键盘录入
			if (br == null)
				br = 
                       new BufferedReader(new InputStreamReader(System.in));
			// 读取数据
			String line = null;
			while ((line = br.readLine()) != null) {
				// 发送数据
				byte[] buf = line.getBytes();
				DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("PresidentsPC"), 10000);
				ds.send(dp);
			}
		} catch (Exception e) {
			System.out.println(e.toString());
		} finally {

			ds.close();
			if (br != null)
				try {
					br.close();
				} catch (Exception e) {
					System.out.println(e.toString());
				}
		}
	}
}

//搞一个线程来接受数据
class ChatThread implements Runnable {
	
	public void run(){
		
		while(true){
			DatagramSocket ds = null;
			try {
	                      ds = new DatagramSocket(10000);//监视10000端口
	                        //获取数据
	                        byte[] buf = new byte[1024];
	                        
	                        DatagramPacket dp = new DatagramPacket(buf,buf.length);
	                        ds.receive(dp);                       
	                        
	                        //获取IP
	                        String ip = dp.getAddress().getHostAddress();
	                        
	                        //输出数据
	                        System.out.println(ip+" :"+new String(buf,0,dp.getLength()));
	                   
	                        
                        } catch (Exception e) {
                        	System.out.println(e.toString());
                        }finally{
                        	ds.close();
                        }
		}
	}
}

如果可以看得懂上面这个程序,并能独立写出来的话,那么UDP传输协议,基本上搞定啦,那么接下来我们继续学习TCP传输协议。

传输协议:TCP

TCP第一步也是创建服务,但是这服务稍微有点不同。客户端的服务是Sokcet,服务端的服务是ServerSocket。无论是UDP,还是TCP,只要多写几次,就熟悉得不得了了,真的。有一套路的,就这死板的格式。

老规矩,先看看Socket的常用的构造方法和普通方法吧

20191018_213250.png

客户端的步骤:

1、建立服务Socket

2、获取输出流,把数据变成字节数组, 通过输出流发送给服务端。

3、关闭输出流,获取输入流,获取反馈信息

4、关闭资源

代码体现:

java
复制代码
//导包
import java.io.*;
import java.net.*;

public class Client {

	public static void main(String[] args) {

		// 创建服务
		Socket s = null;
		try {
			if (s == null)
				s = new Socket("PresidentsPC", 13000);
			//把数据转换成字节数组
			byte[] buf = "阳光沙滩".getBytes();
			
			//获取输出流
			OutputStream out = s.getOutputStream();
			//发送数据
			out.write(buf);
			
			//关闭发送流
			s.shutdownOutput();
			
			//获取输入流,获取反馈信息
			InputStream in = s.getInputStream();
			byte[] buffer  = new byte[1024];
			int len = in.read(buffer);
			
			//打印反馈信息
			System.out.println(new String(buffer,0,len));
		} catch (Exception e) {
			System.out.println(e.toString());
		}finally{
			if(s!=null){
				try{
					s.close();
				}catch(Exception e)
				{
					System.out.println(e.toString());}
				}
		
		}

	}
}

服务端又如何呢,其实还是大同小异的,要是IO知识掌握了,一点问题都没有,闭上眼睛就来了!

步骤如下

1、建立服务ServerSocket服务,然后。用ServerSocket的accept()方法得到Socket服务

2、获取输入流,然后可以得到数据

3、对读到的数据进行处理,该干嘛干嘛去

4、反馈信息给客户端

5、各种关闭资源

如下:

java
复制代码
//导包
import java.io.*;
import java.net.*;

public class Server {

	public static void main(String[] args)throws Exception {

		//创建服务
		ServerSocket ss = new ServerSocket(13000);
		
		Socket s = ss.accept();
		//先搞到IP地址
		String ip = s.getInetAddress().getHostAddress();
		
		//输出链接上来的机器
		System.out.println(ip+"-----connected");
		
		//获取输入流
		InputStream in  = s.getInputStream();
		//读取数据
		byte[] buf = new byte[1024];
		
		int len = 0;
		while((len = in.read(buf))!=-1){
			//打印到控制台上吧
			System.out.println(new String(buf,0,len));
		}
		s.shutdownInput();
		
		//发送反馈信息
		
		OutputStream out = s.getOutputStream();
		
		out.write("服务端收到啦".getBytes());
		
		//关闭资源
		s.close();
		ss.close();
	}

}

把这个例子也搞定了,就可以更深入发学习TCP其他场景的应用了,比如说,上传图片,并发上传图片,还要追求高效,这可以采用缓冲技术。所以,接下来就搞几个应用看看哈!

网络传输应用

下次再写吧,嘻嘻,累了!睡觉先!早安!

java
复制代码
import java.io.*;
import java.net.*;

class ServerForAll {

	public static void main(String[] args) throws Exception {

		// 创建服务
		ServerSocket ss = new ServerSocket(19000);
		// 创建线程
		while (true) {
			Socket s = ss.accept();
			new Thread(new ServerThread(s)).start();
		}

	}

}

class ServerThread implements Runnable {
	// 持有s的引用
	private Socket s;

	public ServerThread(Socket s) {
		this.s = s;
	}

	public void run() {

		// 获取流
		InputStream in = null;
		OutputStream out = null;
		// 把上传的文件直接入到目录下
		OutputStream outPutFile = null;
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip+"---connected");
		
		int count = 0;
		try {
			in = s.getInputStream();
			out = s.getOutputStream();
			File file = new File("Data.jpg");
			if (file.exists())
				file = new File("Data" + "(" + (count++) + ")");
			outPutFile = new FileOutputStream(file);

			// 读取文件
			byte[] buf = new byte[1024];
			int len = 0;
			while ((len = in.read(buf)) != -1) {
				// 写数据
				outPutFile.write(buf, 0, len);
			}
			// 反馈信息
			out.write("上传成功!".getBytes());

			s.close();
			outPutFile.close();
		} catch (Exception e) {
			System.out.println(e.toString());
		}

	}
}




class Client {

	public static void main(String[] args) {
		// 把路径直接用参数传入
		if (args.length == 0) {
			System.out.println("请传入jpg图片的路径参数");
			return;
		}
		if (!args[0].endsWith(".jpg")) {
			System.out.println("图片格式不正确");
			return;
		}

		File file = new File(args[0]);
		if (!file.exists()) {
			System.out.println("文件不存在");
			return;
		}
		// 创建服务
		Socket s = null;
		InputStream in = null;
		try {
			s = new Socket("PresidentsPC", 19000);
			in = new FileInputStream(file);
			// 获取输出流
			OutputStream out = s.getOutputStream();
			byte[] buf = new byte[1024];
			int len = 0;
			while ((len = in.read(buf)) != -1) {
				// 发送数据
				out.write(buf, 0, len);
			}
			// 关闭发送流
			s.shutdownOutput();

			// 获取输入流,获取反馈信息
			InputStream input = s.getInputStream();
			byte[] buffer = new byte[1024];
			int length = input.read(buffer);

			// 打印反馈信息
			System.out.println(new String(buffer, 0, length));
		} catch (Exception e) {
			System.out.println(e.toString());
		} finally {
			if (s != null) {
				try {
					s.close();
				} catch (Exception e) {
					System.out.println(e.toString());
				}
				if (in != null)
					try {
						in.close();
					} catch (Exception e) {
						System.out.println(e.toString());
					}
			}

		}

	}
}

到此,剧终!感谢各位看官,喜欢就分享,喜欢就点赞吧!

本文由 拉大锯 原创发布于 阳光沙滩 , 未经作者授权,禁止转载
评论
0 / 1024
用户头像
写的不错
2021-11-01 11:16回复
用户头像
厉害~
2020-01-01 15:22回复
用户头像
厉害了,知道TCP/UDP的区别,感觉应该再写几遍就记住了,感谢
2019-12-10 13:39回复
回复@Android: 你看完了,厉害哦!可以可以!不用记的,太累了。除非面试,用到的时候,再看看就好。知道就行,混个脸熟。
2019-12-10 13:43回复
回复@拉大锯: 哈哈哈 我正想说感觉记不住,目前只记得个大概是什么,多用几次应该就清楚了
2019-12-10 13:50回复
推荐文章
一篇文章讲清楚雅思、托福、GRE、SAT、GMAT:它们是什么?有什么区别?应该考哪个?
面对IELTS、TOEFL、GRE、SAT和GMAT,你是否感到困惑?本文深度解析五大考试的核心区别:从语言证明到学术能力评估,明确各自适用人群与场景。特别更新2026年托福改革及最新评分体系,通过对比表格与真实申请案例,助你精准定位目标考试,避免无效备考,高效规划海外升学之路。
一篇文章讲清楚 Android 签名:PK8、X509.PEM、JKS 是什么?它们有什么关系?
深入解析Android应用与系统签名的核心文件:PK8、X509.PEM与JKS。本文从非对称加密原理出发,厘清私钥、证书与密钥库的本质区别及相互转换方法,涵盖AOSP平台签名与普通应用发布的实际场景。通过对比V1-V4签名方案及解答常见疑难,助你掌握保障APK完整性与身份认证的关键技术,规避签名丢失或冲突风险。
系统监控运维系统
你是否也深受证书过期、磁盘满载等运维痛点的折磨?排查耗时,影响线上体验。本文分享一款自研运维系统面板,集成证书统一监测、资源预警及WebSSH等功能,实现问题快速定位与处理。附代码共享链接,欢迎参考或二次开发,提升运维效率。
断点说搞个万年历,怎么搞?
想快速拥有一个专属的程序员日历?只需一篇清晰的设计文档,剩下的交给AI!本文带你从零搭建“sob-calendar”项目,集成农历、节气及独特的程序员运势功能。通过实际案例展示如何利用AI高效生成代码并部署上线,让繁琐的开发工作变得轻松有趣,快来体验科技与传统历法的奇妙碰撞吧!
linux服务器的日志、容器清理
本手册提供了一套全面的Linux服务器磁盘清理与排查方法,帮助用户高效管理磁盘空间。通过查看磁盘使用情况、分析Docker占用、清理无用容器和日志,确保系统运行流畅。适合需要优化服务器性能的运维人员参考。
记给网站接入图形验证码
本文分享了如何为个人站点添加图形验证码以提升安全性,详细介绍了使用第三方接口实现验证码功能的过程,并通过代码示例展示了具体实现方式。对于关注网站安全的开发者来说,这篇文章提供了实用的参考价值。
Java开发环境搭建
本文是一份详细的Java开发环境搭建指南,涵盖了Java的发展历史、版本选择及安装配置过程。无论你是初学者还是有经验的开发者,都能从中找到实用的信息和步骤,帮助你快速上手Java开发。
Vue3.js项目的创建
本文详细介绍了如何使用Vue3创建项目,包括Node.js的安装和配置,以及项目的初始化过程。适合初学者学习如何快速搭建Vue3开发环境,并推荐了相关课程供进一步学习。
Network Tools : 您的运维“助手”升级了
Network Tools是一款专为解决运维难题而设计的软件,集设备管理、配置备份、性能监控和告警处理于一体。通过统一的工作台,帮助运维人员更高效地管理资产、定位故障并提升团队协作效率。无论是设备在线状态还是具体问题排查,都能得到全面支持。
Ubuntu 软件安装与彻底卸载指南
本文详细介绍了在 Ubuntu 系统中如何规范安装和彻底卸载 .deb 格式软件,包括依赖修复、残留清理以及图形化工具推荐,适合需要维护系统环境的用户。
JavaWeb开发客户程序更新特殊环境下的骚操作
本文分享了在无外网环境下,如何利用Docker和docker-compose实现高效部署的实战经验。通过基础镜像和本地jar包挂载的方式,解决了内网环境下的依赖问题,适合需要灵活部署方案的技术人员参考。
Linux 防火墙完全指南:从原理到多发行版实战
本文全面解析Linux防火墙的底层原理与主流工具配置,涵盖UFW、firewalld、iptables、nftables等方案,适合不同发行版用户。从基础概念到生产环境加固建议,助你掌握核心安全策略,确保服务器与网络的安全运行。
水上派对英语单词篇
探索FLOATOPIA水上派对的完整指南,涵盖签到流程、场地指引、安全须知、活动安排及夜场舞会等实用英语词汇与对话。无论是初学者还是老手,都能轻松掌握关键术语,享受完美水上体验。
麒麟操作系统下使用 virt-customize 重置虚拟机 root 密码实战
本文详细介绍了在麒麟操作系统环境下使用 virt-customize 工具重置 KVM 虚拟机 root 密码的完整流程,包含安装步骤、常见问题及解决方案,帮助运维人员高效处理密码遗忘或批量初始化场景,避免数据丢失。
浅析JS预编译-函数篇
本文详细讲解了JavaScript中函数的预编译过程,包括AO对象的创建、变量和函数声明的提升,以及执行阶段的变化。适合初学者了解JS执行机制,帮助深入理解代码运行逻辑。
访问Github的另一种姿势
本文介绍了如何通过Watt ToolKit等工具加速访问Github,适合对网络技术感兴趣的读者。内容涵盖工具介绍、下载和使用方法,以及一些实用技巧,值得一看。
使用Gulp压缩JS
本文详细介绍了如何使用Gulp压缩JavaScript文件,特别是支持ES6语法的处理方法。通过实际操作和效果对比,帮助开发者提升代码性能,适合对前端自动化工具感兴趣的读者。
使用Gulp压缩CSS
本文详细介绍了如何使用Gulp工具对CSS文件进行压缩,提升网页加载速度。适合需要优化静态资源的开发者,提供清晰的步骤和示例,帮助快速上手。
从0部署Nuxtjs项目
本文详细介绍了如何将Nuxt.js项目部署到公网,涵盖Node.js安装、环境配置、源码上传及使用PM2启动服务的全过程,适合开发者学习和实践。
Linux 命令行美化利器:tree 命令完全指南(安装 + 全部参数详解)
掌握 Linux 下的 `tree` 命令,快速直观地查看目录结构。本文详细讲解安装方法、参数含义及实战场景,适合开发者和系统管理员提升工作效率。
Linux常用命令(一)
本文详细介绍了Linux基础命令,包括文件操作、系统显示、网络状态、软件包管理等,适合初学者学习和查阅,是掌握Linux系统的实用指南。
大模型推理参数解码:温度、Top-p 与核采样如何塑造生成文本的灵魂
探索大语言模型的采样参数如何塑造生成内容,从温度到Top-p,从惩罚机制到熵控制,揭示背后的信息论原理与实践策略。了解如何通过参数调优,让AI既保持知识的严谨,又拥有创造力的自由。
记从0使用Claude code写代码
本文介绍了如何使用Claude Code搭配DeepSeek进行编程,详细讲解了安装Node.js、全局安装Claude、配置模型以及使用方法。对于开发者来说,这是一份实用的技术教程,尤其适合对AI编程工具感兴趣的读者。
Android-Studio-Gradle同步失败-Library为null的通用排查指南
遇到 Android Studio Gradle Sync 失败时,不要轻易删除全局缓存。本文详细解析了错误原因,并提供了一系列精准的排查步骤和解决方案,帮助开发者快速定位并解决问题,提升开发效率。
PHP实现密码加密
本文详细介绍了Bcrypt密码加密技术及其在PHP中的应用,帮助开发者提升用户密码的安全性。通过实际代码示例,展示了如何使用password_hash和password_verify函数进行密码加密与验证,是学习网络安全知识的实用指南。
WordCloud效果,滚动标签
本文详细介绍了如何在Vue项目中集成WordCloud组件,包括依赖安装、属性配置和使用方法。适合开发者学习如何实现数据可视化功能,提升项目交互体验。
从0使用WordPress搭建一个优美的网站
本文详细介绍了如何使用WordPress搭建一个美观的网站,从安装到主题配置和功能拓展,为读者提供了实用的操作指南。无论是初学者还是有一定经验的开发者,都能从中获得有价值的参考。
JS实现在网站底部添加运行时间
想知道如何在网站底部显示运行时间?本文详细讲解了通过JavaScript实现这一功能的方法,包括时间计算逻辑和代码实现。适合前端开发者学习参考,轻松为网站添加实用功能。
在Vercel上部署Hexo博客
本文详细介绍了如何在Vercel上快速部署Hexo博客,无需后端服务即可实现高效发布。相比传统方式,省去了手动生成和上传静态文件的步骤,更加便捷。适合想要搭建个人博客的开发者参考。
从0搭建一个Hexo博客
本文详细介绍了Hexo博客框架的使用方法,从安装到部署全流程讲解,适合想快速搭建个人博客的技术爱好者。内容清晰易懂,是入门Hexo的理想指南。