网络编程
什么是网络编程
网络编程:
网络:通过多台计算机构建的一个大网
1:为什么需要网络?
多台计算机通过网络连接,进行通信,数据交互、数据共享。
去除地域限制 拉近人与人之间的举例
网络编程的三要素
网络通信的基石:
- 三大基石(ip标示计算机 协议通信规则 端口定位应用程序)
IP
用来表示计算机的,分为ipv4和ipv6
协议
每次进过不同层时,都会添加该层的标示以及遵守不同层的协议。
端口
2个字节 65536个 0-65536之间
- 虚拟的概念
- 0-1024之间的端口是系统保留端口
- 22 21
- 3306 8521 8080 80
public class Test01 {
public static void main(String[] args) {
byte b = 100;// 0110 0100
byte a = 33;// 0001 1100
// 1000 0000 -> 0111 1111
byte n = (byte)(b+a);
System.out.println(n);
}
}
InetAddress
- InetAddress:
封装了一个ip对象 - 一个域名可以映射多个ip地址 多个ip就是多台服务器 单点故障
- 拓展:学习使用一下外网穿透工具(ngrok 花生壳) 可以部署项目到外网上
import java.net.UnknownHostException;
import java.util.Arrays;
public class Test02 {
public static void main(String[] args) throws UnknownHostException {
//获取一个主机InetAddress对象
InetAddress in = InetAddress.getLocalHost();
//使用对象的方法
System.out.println("获取ip地址:"+in.getHostAddress());
System.out.println("主机名称"+in.getHostName());
byte[] buf = in.getAddress();
System.out.println(Arrays.toString(buf));
// 获取对象的方法
InetAddress[] ips = InetAddress.getAllByName("www.baidu.com");
for(InetAddress ip:ips) {
System.out.println(ip.getHostAddress()+"=="+ip.getHostName());
}
}
}
TCP
启动顺序
1: 客户端和服务器开启是有先后顺序的
先启动服务器 然后启动客户端
安全的
socket对象
1: 客户端称之为socket对象
2:服务器称之为serversocket对象
3:客户端在创建时需要指定ip以及端口
4:服务器创建时需要指定监听端口
5:数据的收发都是通过流完成的 所有数据信息都可以通过socket获取输入/输出流 getInputStream/getOutputStream
6: 对于服务器而言,获取客户端的socket对象 accept方法 (阻塞方法)
编码套路
client
-
//创建socket对象(ip,端口)
-
//获取流对象(你要干嘛?)
-
//发送/接受数据信息
-
//关闭
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
/*
*
* 使用Socket模拟客户端给服务端发送数据信息
*
*
*/
public class ClinetA {
public static void main(String[] args) throws IOException {
// 1: 创建客户端socket对象
Socket client = new Socket(InetAddress.getLocalHost(),10001);
// 2:创建流对象 发送数据信息
OutputStream os = client.getOutputStream();
// 3:写出数据到服务器
os.write("嘿嘿".getBytes());
// 4:关闭资源
os.close();
client.close();
}
}
server
- //创建serversocket对象(端口)
- //通过accept方法获取客户端socket对象
- //获取流对象(你要干嘛?)
- //发送/接受数据信息
- //关闭
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* 根据ServerSocket对象 创建服务器套接字 接受客户端发送信息
* @author wawjy
*
*/
public class ServerA {
public static void main(String[] args) throws IOException {
//1:创建ServerSocket对象
ServerSocket server = new ServerSocket(10001);// 监听该端口
//2:通过accept方法获取连接的socket对象
Socket client = server.accept();//阻塞方法
//3:获取客户端发送的数据信息
InputStream is = client.getInputStream();
//4:读取数据信息
byte[] buf = new byte[1024];
int len = is.read(buf);
//5:分析数据
System.out.println(new String(buf,0,len));
//6:关闭资源
is.close();
client.close();
}
}
UDP
基于发送方和接受方 都是通过DatagrameSocket对象去指定
1: 启动发送方不会报错
不安全
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Arrays;
public class Rec {
public static void main(String[] args) throws IOException {
//1:创建接收方对象
DatagramSocket rec = new DatagramSocket(10001);
//2:创建接受数据包对象
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
//3:接受发送方发送数据信息
rec.receive(dp); //会将数据信息填充在DatagramPacket对象中 阻塞方法
//4:分析数据
InetAddress in = dp.getAddress();
byte[] recBuf = dp.getData();
int length = dp.getLength();
int port = dp.getPort();
String data = new String(recBuf,0,length);
System.out.println(in.getHostName()+"=="+data+"=="+port);
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
/*
*
* 基于udp发送数据信息
*
*/
public class Send {
public static void main(String[] args) throws IOException {
//1:创建发送方对象
DatagramSocket send = new DatagramSocket(9999);
//2:构建发送方的数据包对象 buf 发送数据的字节数组 length发送数据的长度 发送到那个ip去 port发送到那个端口
String str = "老薛已经上线";
byte[] buf = str.getBytes();
int len = buf.length;
InetAddress ip = InetAddress.getLocalHost();
int port = 10001;//接受方的端口
DatagramPacket dp = new DatagramPacket(buf, len, ip, port);
//3:发送信息
send.send(dp);
//4;关闭
//send.close();
}
}
TCP和UDP读区别
TCP:
- 面向有连接 相当于打电话(点名 答到 确认) 3次握手
- 安全 发送数据是无长度限制
- 慢
UDP:
- 面向无连接 相当于发短信
- 不安全
- 发送的数据长度有限制(64k)
- 快
URL和URLConnection
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
public class Test01 {
public static void main(String[] args) throws IOException {
//创建URL对象
URL url = new URL("https://www.sina.com.cn/");
InputStream is = url.openStream();
byte[] buf = new byte[1024*10];
int len = is.read(buf);
System.out.println(new String(buf,0,len));
}
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
public class Test02 {
public static void main(String[] args) throws MalformedURLException {
URL url = new URL("https://www.sina.com.cn/");
//获取url定义的资源的一些内容
System.out.println(url.getDefaultPort());
System.out.println(url.getHost());
System.out.println(url.getProtocol());
//很重要 https://192.168.1.1/login?uname=zhangsan&pwd=123
String path = url.getPath();
System.out.println("获取资源路径:"+path);// 域名后 ?前的内容称之为资源路径
String parm = url.getQuery();
System.out.println("获取请求参数:"+parm);//资源路径?后面的所有内容都是当前请求发送的参数
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
/*
* 对于基于http协议下头信息的 获取/设置方法
*/
public class Test03 {
public static void main(String[] args) throws IOException {
//创建URL对象
URL url = new URL("https://www.sina.com.cn/");
//通过资源对象获取到连接该资源的链接对象
URLConnection conn = url.openConnection();
//打开链接
conn.connect();//建立连接
//获取一些有用信息
System.out.println(conn.getConnectTimeout());
System.out.println(conn.getContentType());
System.out.println(conn.getContentLength());
System.out.println(new Date(conn.getDate()));
//读取
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
StringBuilder sb = new StringBuilder();
String str = "";
while((str=reader.readLine())!=null) {
sb.append(str);
sb.append("\r\n");
}
System.out.println(sb.toString());
}
}
API
校验身份信息
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
*
* 320926 19551117 52 7 6
*
* 行政号
* 19551117 出生日期
* 52 当天第几个出生的 7(奇数为男 偶数为女)
* 6 校验位
* @author wawjy
*
*/
public class Test04 {
public static void main(String[] args) throws IOException {
//声明URL对象%E8%8B%8F%E5%B7%9E
URL url = new URL("http://v.juhe.cn/weather/index?format=2&cityname=%C4%CF%B2%FD" +
"&key=ed37c741fc189c1993f14da1833a0f6d");
//通过资源对象获取到连接该资源的链接对象
URLConnection conn = url.openConnection();
//打开链接
conn.connect();//建立连接
//读取
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
StringBuilder sb = new StringBuilder();
String str = "";
while((str=reader.readLine())!=null) {
sb.append(str);
sb.append("\r\n");
}
System.out.println(sb.toString());
}
}
集合
集合:数据集合 (用来存储数据的集合)
-
1:为什么需要学习java中的集合框架:
学习数组可以用来存储数据:
数组的存储数据的弊端:
a:存储相同数据类型的有序集合
存储的数据是相同类型的
b:数组存储数据时 需要指定当前数组的长度而且长度不可变 (定长)
需求:使用数组存储学生信息 效率变低
使用数组存储每天的新闻信息就是由于在大多数的应用场景中,数据都是动态的,导致数组存储要么浪费空间,要么浪费效率
-
2:java提供了一套功能强大的集合框架,来帮助存储数据信息。
-
3:为什么java提供了这么多集合对象存储数据信息?
这么多集合对象用来在不同的需求场景使用。
本质上而言 其实不同的集合对象底层存储实现方案不同 不同的存储结构 适用不同的需求
1 3 6 9
一张图
3个知识点
泛型:
<E> 数据类型
迭代器:
Iterable 是java.lang包下的接口 实现改接口都能够作为foreach的目标
Iterator 是java.util包下的接口 迭代器 用来迭代当前集合对象的
Iterator 是一个接口 ArrayList中通过内部类完成了对于改接口的实现 获取的其实是实现类对象
6个接口
Collection:
定义:
public interface Collection<E> extends Iterable<E>
<E> --> Object
Iterable: 接口 凡是继承/实现了Iterable的类 都能够作为foreach的目标
Iterable 是java.lang包下的接口 实现改接口都能够作为foreach的目标
Iterator 是java.util包下的接口 迭代器 用来迭代当前集合对象的
常见方法:
add 、clear、remove、addAll、removeAll、retainAll、size、isEmpty、contains、
containsAll、iterator
迭代方法:
foreach、迭代器
import java.util.ArrayList;
import java.util.Collection;
/*
* Collection:
* 存储元素的特点 无序 可重复 对于所有的集合框架中的对象 只能存储引用类型
*
* 添加元素
* add(Object) 添加元素 返回是否添加成功 true/false
* addAll(Coll) 添加一个集合
* 删除元素
* clear()清空所有元素
* remove()移除一个
* removeAll(Coll) 移除交集
* retainAll(Coll) 保留交集
* 修改元素
* 没有修改元素
* 查看元素
* isEmpty
* size
* contains
* containsAll
* 迭代元素
*
*
*
*
*
* @SuppressWarnings : 注解 用来抑制警告
*
*/
@SuppressWarnings("all")
public class Test01 {
public static void main(String[] args) {
// 学习接口中的方法 接口指向实现类对象
Collection coll = new ArrayList();
//添加元素
coll.add("java");// Object obj = "java" 自动类型转换
coll.add(1);// Integer in1 = Integer.valueOf(1); Object obj = in1;
//添加元素
Collection coll1 = new ArrayList();
coll1.add("html");
coll1.add("spring");
System.out.println("往coll中添加coll1:"+coll.addAll(coll1));
//删除元素:
//coll.clear();
System.out.println("移除不存在的元素:"+coll.remove("spring"));
//System.out.println(coll.removeAll(coll1));
System.out.println("coll中的元素:"+coll);
System.out.println(coll.retainAll(coll1));
System.out.println("coll中的元素:"+coll);
//查看元素
System.out.println("查看当前集合是否为null:"+coll.isEmpty());
System.out.println("查看当前集合元素个数:"+coll.size());
System.out.println("查看当前集合是否包含元素1:"+coll.contains("1"));
}
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
// 目前情况下不要再迭代元素过程中强转类型 可能会引发问题 classcaseexception
public class Test02 {
public static void main(String[] args) {
//创建集合对象
Collection coll = new ArrayList();
//添加元素
coll.add("String");
coll.add("1");
coll.add("Integer");
coll.add("Scanner");
//迭代元素
System.out.println("foreach循环迭代");
for(Object obj:coll) {
String str = (String)obj;
System.out.println(str);
}
System.out.println("iterator 迭代器");
Iterator it = coll.iterator();//实现类对象
while(it.hasNext()) {//下面是否存在元素 如果存在元素 返回true 如果不存在返回false
//获取元素
System.out.println(it.next());
}
System.out.println("迭代器的变种写法");
for(Iterator it1 = coll.iterator();it1.hasNext();) {
System.out.println(it1.next());
}
}
}