Java基础——网络编程
一.网路编程知识
意义:过去我们IO流是把本地的文件传递而已,网络编程是把自己电脑的数据传递给另一台电脑,并且回馈信息。这是数据通讯
1.通讯三要素
1.1 IP地址
(1)获取对方主机IP
1.2 端口号
(1)数据发送到对方主机指定的应用程序上,为了区别主机上的应用程序,会定义一些数字标识(端口)来区分每一个应用程序。这个端口也被称为逻辑端口(只有相同的应用程序才能解析相应的数据,所以要发送给指定的应用程序)每一个网络程序都有一个端口号
1.3 传输协议
(1)定义通讯规则,这种规则被称为通信协议。两台主句必须按照同种协议才可以实现通信,协议不相同则不能通信。国际组织定义了通用协议TCP/IP。
游戏通信举例:
<1>.魔兽世界:
a.为什么全世界的玩家都能通信?因为都全世界都在用通用的TCP/IP协议
b.为什么你能看见其他玩家?首先你向暴雪服务器发送信息,然后期服务器反馈给你信息,你解析即可得到其他玩家的位置。
c.为什么你能向好友发送信息?你们加好友就是获取了对方的IP地址,然后发送信息就是普通的数据通信原理
<2>.CS
CS局域网连接如何实现?获取对方IP,获取对方CS客户端端口,都有通用协议TCP/IP。如果几个人用自己的协议,如IPX/NetBIOS,那么其他使用TCP/IP协议的人是无法连如这个局域网的
2.重点知识
(1)子网掩码:把一块区域划分到一块相当于局域网当中,这片区域都会用一个外网IP地址。子网掩码是为了多人共用一个地址而出现的。
(2)IPV6:定义了足够多的IP地址,其中不但有数字而且加入了字母
(3)端口号:0~65575端口可任选,不过0~1024端口被系统所用或保留端口。应用程序端口后未设定,系统随机分配。web服务:80;Tomcat:8080;mysql:3306
(4)本地回环地址:127.0.0.1 主机名:localhost,网络主机名www.baidu.com,前边是万维网标识,baidu自定义主机名,com主机所属区域
(5)TCP——Transmission Control Protocol UDP——User Datagram Protocol
(6)192.168.1.0不能用,这个地址代表一个网络地址,代表一个网络段;192.168.1.255代表广播地址,能够给该网络内所有存活主机发广播
3.参考模型
3.1 OSI参考模型( 7层)
3.2 TCP/IP参考模型( 4层)
(1)应用层:主要对应的——>JavaWeb(HTTP协议——Hypertext transfer protocol)
(2)传输层:(TCP/UDP)——>Java网络编程
(3)网际层:(IP)——>Java网络编程
(4)主机至网络层:计算机网络大学所学
二.Java网络编程
1.InetAddress类
方法摘要 | |
---|---|
tatic InetAddress
|
getLocalHost() 返回本地主机。throw UnknownHostException() |
static InetAddress
|
getByName(String host) 在给定主机名的情况下确定主机的 IP 地址。throw UnknownHostException() |
static InetAddress[]
|
getAllByName(String host) 在给定主机名的情况下,根据系统上配置的名称服务返回其 IP 地址所组成的数组。throw UnknownHostException() |
String
|
getHostAddress() 返回 IP 地址字符串(以文本表现形式)。 |
String
|
getHostName() 获取此 IP 地址的主机名。 |
2.Socket
(1)科普:最早赛扬系列CPU,CPU要插在主板相应的插槽上,最早的插槽为Socket 370,这里370指的是CPU的帧角数,370的插槽能插370帧角的CPU
(2)这里的Socket是指软件的Socket,每个软件都是一个插槽(Socket)准备接受对方传过来的数据。所以想要通信,必须先要有插槽(Socket)
(3)通常所说网络通信及Socket通信,通信的两端必须都有Socket,数据通过IO流传输
3.传输协议
3.1 UDP协议
(1)特点:面向无连接,无连接——网络通信有两端,你不用在意另外一端在与否,都向它发送数据包,没找到的话包则丢掉;通讯无需建立连接。所以速度快,是不可靠协议。将数据及源和目的封装成数据包,数据大小限制在64K以下。
(2)对应应用:QQ聊天、视频会议(凌波视频)
(3)原理:远程视频就算数据丢了也无所谓。可像下载就不建议使用这种协议,因为存在本地的数据必须保证数据的完整性
(4)模型:步话机(通过调节至共同频段来实现通话,对方没开的话你发数据对方无法收到)
3.1.1 DatagramSocket类
意义:用来发送和接收数据包的套接字
构造方法摘要 | |
---|---|
DatagramSocket() 构造数据报套接字并将其绑定到本地主机上任何可用的端口。 |
|
DatagramSocket(int port) 创建数据报套接字并将其绑定到本地主机上的指定端口。 |
方法摘要 | |
---|---|
void
|
receive(DatagramPacket p) 从此套接字接收数据报包。(阻塞式方法) |
void
|
send(DatagramPacket p) 从此套接字发送数据报包。 |
void
|
close() 关闭此数据报套接字。 |
3.1.2 DatagramPacket类
意义:因为数据包是一个复杂事物,包括源端口,源地址,目的端口,目的地址,所有封装为对象
构造方法摘要 | |
---|---|
DatagramPacket(byte[] buf, int length) 构造 DatagramPacket ,用来接收长度为 length 的数据包。(定义要接受的数据包)
|
|
DatagramPacket(byte[] buf, int length, InetAddress address, int port) 构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。(定义要发送的数据包)
|
方法摘要 | |
---|---|
InetAddress
|
getAddress() 返回某台机器的 IP 地址,此数据报将要发往该机器或者是从该机器接收到的。 |
byte[]
|
getData() 返回数据缓冲区。 |
int
|
getLength() 返回将要发送或接收到的数据的长度。 |
int
|
getPort() 返回某台远程主机的端口号,此数据报将要发往该主机或者是从该主机接收到的。 |
3.1.3 使用方法( 代码)
/*
需求:练习用Socket实现两台计算点间的的数据发送与接收
步骤:1.通过DatagramPacket来为数据打包2.通过DatagramSocket来发送数据包3.通过DatagramSocket来接收DatagramPacket数据包*/import java.net.*;class SocketSendPractice
{public static void main(String[] args)throws Exception{//建立UDP的Socket的服务DatagramSocket ds = new DatagramSocket();//建立数据缓冲区byte[] buf = "聊天程序的第一步".getBytes();//获取本地主机的IP对象InetAddress ia = InetAddress.getLocalHost();//建立需要发送的数据包DatagramPacket dp = new DatagramPacket(buf,buf.length,ia,10000);//发送数据ds.send(dp);//关闭资源ds.close();}
}class SocketReceivePractice
{public static void main(String[] args)throws Exception{//建立Socket服务DatagramSocket ds = new DatagramSocket(10000);//建立接收数据的缓冲区byte[] buf = new byte[1024];//建立接收数据的数据包DatagramPacket dp = new DatagramPacket(buf,buf.length);//接收数据ds.receive(dp);System.out.println(new String(dp.getData(),0,dp.getLength()));ds.close();}
}
3.1.4 键盘录入(UDP 代码)
import java.net.*;
import java.io.*;/**
*键盘输出数据发送到指定PC,使用UDP传输
*/
class UdpSend
{public static void main(String[] args)throws Exception{//代码观看方便未处理异常//建立发送断SocketDatagramSocket ds = new DatagramSocket(8888);//获取键盘录入//BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));BufferedInputStream bufis = new BufferedInputStream(System.in);//建立对方IP地址对象InetAddress ip = InetAddress.getLocalHost();//String line = "";int line;byte[] buf = new byte[1024];while((line=bufis.read(buf))!=-1){//buf = line.getBytes();//封装数据到包中DatagramPacket dp = new DatagramPacket(buf,line,ip,10000);ds.send(dp);}bufis.close();ds.close();}
}class UdpReceive
{public static void main(String[] args)throws Exception{//建立发送断SocketDatagramSocket ds = new DatagramSocket(10000);//建立接收数据的包byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf,buf.length);while(true){ds.receive(dp);System.out.print(dp.getAddress().getHostName()+":"+dp.getPort()+"......"+new String(dp.getData(),0,dp.getLength()));}//ds.close();}
}
3.1.5 仿QQ的聊天GUI界面实现( 代码)
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.text.*;
import java.util.*;/**
*实现主机间的聊天并且用GUI实现窗口
*1.ChattingFrame类是界面实现类,Send是发送数据线程类,Receive是接收数据线程类
*2.界面类构建时就对开启接受线程,实现实时接收数据的功能
*3.没输入一条数据都会建立一个线程发送对象来发送数据包,并且分别向本机与对方机发送数据包
*/class NewChattingFrameTest
{public static void main(String[] args)throws Exception{DatagramSocket dsSend = new DatagramSocket();DatagramSocket dsReceive = new DatagramSocket(10000);new ChattingFrame(dsSend,dsReceive);}
}class ChattingFrame
{private Frame f;private TextArea taSend,taReceive;private Panel pSend,pReceive;private Button b;private DatagramSocket dsSend,dsReceive;//这个窗体是为了传送接收信息的,构造时需要发送和接收数据的包ChattingFrame(DatagramSocket dsSend,DatagramSocket dsReceive){this.dsSend = dsSend;this.dsReceive = dsReceive;init();Receive r = new Receive(dsReceive,taReceive);new Thread(r).start();}public void init(){f = new Frame("聊天程序");f.setBounds(400,200,500,420);f.setLayout(new BorderLayout(10,10));//建立上下主面板pSend = new Panel();pSend.setPreferredSize(new Dimension(300,100));pReceive = new Panel();pReceive.setPreferredSize(new Dimension(300,300));//布局下边的发送面板内的内容pSend.setLayout(new BorderLayout(10,10));taSend = new TextArea();taSend.setPreferredSize(new Dimension(250,60));b = new Button("发送");b.setPreferredSize(new Dimension(30,20));pSend.add(taSend,BorderLayout.CENTER);pSend.add(b,BorderLayout.EAST);//布局上边接收面板的内容pReceive.setLayout(new BorderLayout());taReceive = new TextArea();taReceive.setEditable(false); pReceive.add(taReceive);//把主面板添加进窗体内f.add(pSend,BorderLayout.SOUTH);f.add(pReceive,BorderLayout.CENTER);myEvent();f.setVisible(true);}public void myEvent(){f.addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent e){System.exit(0);}});//添加按钮监听,点击按钮发送信息b.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){//建立发送线程并发送数据new Thread(new Send(dsSend,taSend.getText())).start();//清空文本区域taSend.setText("");}});//添加键盘监听,点击回车发送数据taSend.addKeyListener(new KeyAdapter(){public void keyPressed(KeyEvent e){if(e.getKeyCode()==KeyEvent.VK_ENTER && !e.isControlDown()){e.consume();new Thread(new Send(dsSend,taSend.getText())).start();taSend.setText("");}}});}
}class Send implements Runnable
{private DatagramSocket ds;private String taSend;//构造时需要接收要发送的数据和发送数据的包Send(DatagramSocket ds,String taSend){this.ds = ds;this.taSend = taSend;}public void run(){try{if(taSend==null)return;byte[] buf = taSend.getBytes();if(buf.length!=0){DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("10.23.12.86"),10000);//发送给指定IPDatagramPacket owndp = new DatagramPacket(buf,buf.length,InetAddress.getLocalHost(),10000);//发送给本机ds.send(dp);ds.send(owndp);}elsereturn;}catch (UnknownHostException e){throw new RuntimeException("未知主机");}catch(Exception e){throw new RuntimeException("IO异常");}}
}class Receive implements Runnable
{private DatagramSocket ds;private TextArea taReceive;//构造时需要接收数据的包和输出接收数据的窗体组件TextAreaReceive(DatagramSocket ds,TextArea taReceive){this.ds = ds;this.taReceive = taReceive;}public void run(){//为实现边输入边接收数据的功能,接收程序必须一直执行,不能停止,所以定义无限循环while(true){try{byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf,buf.length);ds.receive(dp);int length = dp.getLength();//接收的数据以字符串形式存储String content = new String(dp.getData(),0,length);//获取现在的时间以字符串形式存储SimpleDateFormat sdf = new SimpleDateFormat("H:m:s");String date = sdf.format(new Date());//排列出要显示的信息样式保存在一个字符串当中String textReceive = dp.getAddress().getHostName()+" "+date+" \r\n"+content+"\r\n\r\n";//把定义好的字符串添加进taRecieve组件taReceive.append(textReceive);}catch (Exception e){throw new RuntimeException("接收出现错误");}}}
}
3.2 TCP协议
(1)特点:面向连接,面向连接——只有对方在才发送数据,否则不发送;通讯需建立连接。可实现大数据的传输,通过三次握手完成连接,是可靠协议。必须建立连接,速率稍低。三次握手——老师问你在吗?1次;我回答我在。2次;老师说我知道你在了。3次。通过这三次握手可完成TCP通道的建立
(2)模型:电话(建立通话连接,通话数据在通道中来回传输)
3.2.1 Socket类
意义:实现了客户端的套接字。建立对象时,通路一建立就会有一个Socket流,其中既有输入流也有输出流,可以用她们对数据进行操作
构造方法摘要 | |
---|---|
Socket() 通过系统默认类型的 SocketImpl 创建未连接套接字 |
|
Socket(InetAddress address, int port) 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。 |
|
Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号。 |
方法摘要 | |
---|---|
void
|
connect(SocketAddress endpoint) 将此套接字连接到服务器。 |
InetAddress
|
getInetAddress() 返回套接字连接的地址。 |
int
|
getPort() 返回此套接字连接到的远程端口。 |
InputStream
|
getInputStream() 返回此套接字的输入流。 |
OutputStream
|
getOutputStream() 返回此套接字的输出流。 |
void
|
shutdownInput() 此套接字的输入流置于“流的末尾”。 |
void
|
shutdownOutput() 禁用此套接字的输出流。 |
void
|
close() 关闭此套接字。 |
3.2.2 ServerSocket类
意义:服务端会获取每一个客户端Socket的对象,并且通过这个对象的输入、输出流来向相应客户端发送数据。获取客户端对象通过accept()方法完成
构造方法摘要 | |
---|---|
ServerSocket(int port) 创建绑定到特定端口的服务器套接字。 |
|
ServerSocket(int port, int backlog) 利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。(指的是连接到服务器中的客户端的最大个数) |
方法摘要 | |
---|---|
Socket
|
accept() 侦听并接受到此套接字的连接。(阻塞式方法) |
void
|
close() 关闭此套接字。(可选操作,服务器一般不用关闭) |
3.2.3 代码练习(键盘录入)
3.2.4 代码练习 (上传文件)
import java.io.*;
import java.net.*;class Client
{public static void main(String[] args)throws Exception{//指定服务器地址、端口Socket s = new Socket(InetAddress.getLocalHost(),10000);BufferedReader bufr = new BufferedReader(new FileReader("d:\\java.java"));//获取Socket的输入、输出流对象并且封装为高效率BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));PrintStream out = new PrintStream(s.getOutputStream(),true);//向服务器写入文件数据String line = null;while((line=bufr.readLine())!=null){out.println(line);}out.shutDownOutput();String str = in.readLine();System.out.println(str);s.close();}
}class Server
{public static void main(String[] args)throws Exception{//建立服务器Socket对象ServerSocket ss = new ServerSocket(10000);+Socket s = ss.accept();//获取Socket的输入、输出流对象并且封装为高效率BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));PrintStream out = new PrintStream(s.getOutputStream(),true);//把读取到的数据写入到本地文件中PrintWriter pw = new PrintWriter(new FileWriter("E:\\哈哈.java"),true);String line = null;while((line=in.readLine())!=null){if("over".equals(line))break;pw.println(line);}//Thread.sleep(10000);out.println("传输成功");s.close();}
}
3.2.5 代码练习(多线程上传图片)
import java.io.*;
import java.net.*;class TcpClient
{public static void main(String[] args)throws Exception{File file = new File("1.jpg");Socket s = new Socket(InetAddress.getLocalHost(),10000);BufferedInputStream bufis = new BufferedInputStream(new FileInputStream(file));BufferedInputStream bufin = new BufferedInputStream(s.getInputStream());OutputStream bufout = s.getOutputStream();//注意客户端和服务端尽量统一写入和发出的流byte[] buf = new byte[1024];int len;while((len=bufis.read(buf))!=-1){bufout.write(buf,0,len);}s.shutdownOutput();len = bufin.read(buf);System.out.println(new String(buf,0,len));bufis.close();s.close();}
}class TcpServer
{public static void main(String[] args)throws Exception{ServerSocket ss = new ServerSocket(10000);while(true){Socket s = ss.accept();new Thread(new ThreadServer(s)).start();//每个用户都会创建多个线程}//ss.close();}
}class ThreadServer implements Runnable
{private Socket s;ThreadServer(Socket s){this. s = s;}public void run(){String ip = null;try{int count = 1;File file = new File("上传文件(1).jgp");while(file.exists())file = new File("上传文件("+(++count)+").jgp");//用户创建多个文件ip = InetAddress.getLocalHost().getHostName();System.out.println(ip+"......conect.......");InputStream bufin = s.getInputStream();PrintWriter out = new PrintWriter(new OutputStreamWriter(s.getOutputStream()),true);FileOutputStream fos = new FileOutputStream(file);byte[] buf = new byte[1024];int len;while((len=bufin.read(buf))!=-1){fos.write(buf,0,len);}out.println("上传完毕");fos.close();s.close();}catch (Exception e){throw new RuntimeException(ip);}}
}
3.2.6 InetSocketAddress类--->实现SocketAddress接口
注1:此类与InetAddress类不同之处在于封装了IP地址与端口号
用法:Socket类有空参构造函数,可以通过connect(SocketAddress sa)这个方法关联服务端地址
4. URL类
构造方法摘要 | |
---|---|
URL(String spec) 根据 String 表示形式创建 URL 对象。
|
|
URL(String protocol, String host, int port, String file) 根据指定 protocol 、host 、port 号和 file 创建 URL 对象。
|
方法摘要 | |
---|---|
boolean
|
equals(Object obj) 比较此 URL 是否等于另一个对象。 |
String
|
getFile() 获取此 URL 的文件名。
|
String
|
getHost() 获取此 URL 的主机名(如果适用)。
|
String
|
getPath() 获取此 URL 的路径部分。
|
int
|
getPort() 获取此 URL 的端口号。
|
String
|
getProtocol() 获取此 URL 的协议名称。
|
String
|
getQuery() 获取此 URL 的查询部分。(获取地址参数信息)
|
URLConnection
|
openConnection() 返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接。(会连接URL指定主机,返回连接对象)
|
5.URLConnection类
意义:这是连接对象,已经实现Socket客户端与服务端之间的连接,无需建立Socket对象。并且次对象内部封装了HTTP协议,能够解析http响应头信息
注1:能够解析获取http响应头数据
方法摘要 | |
---|---|
InputStream
|
getInputStream() 返回从此打开的连接读取的输入流。 |
OutputStream
|
getOutputStream() 返回写入到此连接的输出流。 |
6. 浏览器与服务器原理
6.1 服务器:自定义
import java.net.*;
import java.io.*;/**
*客户端:浏览器
*服务端:自定义
*/class java
{public static void main(String[] args)throws Exception{ServerSocket ss = new ServerSocket(10000);Socket s = ss.accept();BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));PrintStream pw = new PrintStream(s.getOutputStream());String line = null;while((line=bufr.readLine())!=null){//这里必须注释掉才能退出read()方法,因为客户端浏览器write()方法未添加结束标记System.out.println(line);}pw.println("欢迎");s.close();}
}
这个程序接收到浏览器发送来的数据为:(打印在控制台上的数据)
GET / HTTP/1.1
Host: localhost:10000
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36 SE 2.X MetaSr 1.0
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
这是HTTP请求消息头,是客户端浏览器发送过来的请求
6.2 浏览器:自定义
import java.net.*;
import java.io.*;/**
*客户端:自定义浏览器
*服务端:Tomcat服务器
*/class Client
{public static void main(String[] args)throws Exception{//向Tomcat服务器发送数据Socket s = new Socket(InetAddress.getLocalHost(),80);PrintWriter pw = new PrintWriter(s.getOutputStream());//向Tomcat服务器发送Http请求消息头pw.println("GET /myWeb/doing.html HTTP/1.1");pw.println("Accept: */*");pw.println("Accept-Language: zh-CN,zh;q=0.8");pw.println("Host: localhost");pw.println("Connection: closed");pw.println();pw.println();BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));String line = null;System.out.println(188);while((line=bufr.readLine())!=null){System.out.println(188);System.out.println(line);//打印Tomcat返回的数据}s.close();}
}
Java基础——网络编程相关推荐
- JAVA基础 网络编程
JAVA基础 网络编程 网络我们每天都会用到的,在我们生活中占的地位也在不断的提高,我们下面就简单了解下网络编程的内容. 想要学习网络编程,首先就需要了解网络编程包含哪些内容. 网络编程包括 IP节点 ...
- 学习笔记-java基础-网络编程
刚在培训机构学习完JAVA基础和WEB,感觉边学边忘.就把这作为记忆的笔记,我也不知道要不要记笔记,写在本子上太耗费时间了. 一.要想实现网络通信,首先要解决两个问题: ①:如何从网络中定位到一台或多 ...
- 黑马程序员——java基础---网络编程
------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS ...
- java基础-网络编程
1.网络模型: OSI参考模型.TCP/IP参考模型 数据传输的过程:向下走:封包 向上走:拆包 向上走一直拆包,直到得到数据. 2.网络通讯要素 ip地址.端口号.传输协议 Ip和端口用来找对 ...
- java基础网络编程
利用网络,实现两台计算机之间的互相联通.交互. 网络编程有两类: UDP 一种无连接的传输层协议.无连接:指不需要知道对方在不在,只负责发数据传输出去,而对方可能不在,数据便会丢失,所以是不稳定的. ...
- 黑马程序员——Java基础——网络编程1
------- android培训.java培训.期待与您交流! ---------- 网络编程1 一.获取IP 网络编程主要在传输层 :TCP(Transmission Control Pr ...
- Java基础(网络编程基础)
1.软件结构 C/S:客户端和服务器(QQ.微信) B/S:浏览器和服务器(火狐.IE.谷歌) 2.网络通信协议 网络通信协议: 通过计算机网络可以使多台计算机实现连接,位于同一个网络中的计算机在进行 ...
- IT十八掌Java基础 网络编程
网络编程 计算机网络 是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统. 网 ...
- java基础----网络编程
网络编程 1.什么是网络?网络模型?网络四要素? 网络: 在计算机领域中网络是信息传输,接收,共享的虚拟平台,通过它把各个点,面,体的联系到一起,从而实现这些资源的共享. 网络模型: 计算机网络是指由 ...
最新文章
- NC19814最短路 LCA+bfs暴力
- 【python】【h5py】TypeError: Can‘t convert element to hsize_t
- java中jtansforms,Java3D中的viewplatform的旋转
- SAP ABAP一组关键字 IS BOUND, IS NOT INITIAL和IS ASSIGNED的用法辨析
- [渝粤教育] 广东-国家-开放大学 21秋期末考试Java程序设计基础10232k2
- html笔记(四)弹性盒+响应式
- 七、区块链如何运用merkle tree验证交易真实性
- 前端跨域请求get_(单点登录)跨域SSO看这篇文章就够了:前端篇
- 获取 子文件夹 后缀_后期制作老司机教你一键批量生成项目文件夹
- OpenShift 4 - 通过Maven镜像加速Java应用构建速度
- 2019 开源安全报告:开发者安全技能短板明显,热门项目成漏洞重灾区!
- 2009年程序员考试大纲
- coolpro2 剪切并淡出
- Java课程设计- 记事本代码
- html5图片并列排版,图片并列排版实现
- pycharm没有python interpreter_pycharm无法设置interpreter?
- Fallback class must implement the interface annotated by @FeignClient
- mac 卸载php版本,mac osx 更改自带php版本
- 机器学习与算法(12)--最小角回归(LARS)
- 出自阿里P8之手的这份微服务架构实践手册,为何能霸榜GitHub一周