目录
1. 网络编程
TCP
- 通信流程
- 代码实现
服务器端
public static void Server() throws IOException{
//创建端口
ServerSocket ss = new ServerSocket(8080);
System.out.println("服务器启动");
//把对象Socket传入skt(客户端)
Socket skt = ss.accept();
System.out.println("客户端已连接");
//接收客户端信息 输入流
InputStream is = skt.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
//向客户端打印流
OutputStream os = skt.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
PrintWriter bw = new PrintWriter(osw);
String temp = null;
while((temp = br.readLine()) != null){
System.out.println("读出客户端发的信息"+temp);
bw.println("给客户端发的消息:"+temp);
bw.flush();
}
//关闭流
bw.close();
skt.close();
ss.close();
}
用户端
public static void client() throws IOException{
Socket skt = new Socket("localhost",8080);
//向服务端输出
OutputStream os = skt.getOutputStream();
//转字符流
OutputStreamWriter osw = new OutputStreamWriter(os);
PrintWriter pw = new PrintWriter(osw);
Scanner sc =new Scanner(System.in);
String msg = sc.nextLine();
//接受来自服务器的消息
InputStream is = skt.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
while(true){
pw.println(msg);
pw.flush();
//读出服务器发给我的消息
System.out.println(br.readLine());
//循环输入
msg = sc.nextLine();
}
}
UDP
- 类 DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议网络程序。*
- UDP数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。
- DatagramPacket 对象封装了UDP数据报,在数据报中包含了发送端的IP 地址和端口号以及接收端的IP地址和端口号。
- UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和
接收方的连接。如同发快递包裹一样。
服务器端
// 打开UDP对象
DatagramSocket ds = new DatagramSocket(10000);
// 声明一个字节数字,用来存放收到的数据
byte[] buf = new byte[1024];
// 包接收器,把接收的数据保存到数组中
DatagramPacket dp = new DatagramPacket(buf, buf.length);
// 阻塞式接收
while (true) {
// 监听接收
ds.receive(dp);
// 字节数字输入流
ByteArrayInputStream bais = new ByteArrayInputStream(buf);
// 转换为数据流
DataInputStream dis = new DataInputStream(bais);
// 读取数据
String msg = dis.readUTF();
// 如果是exit 则结束服务端
if (msg.equalsIgnoreCase("exit")) {
break;
}
System.out.println(msg);
}
用户端
public static void test02() throws Exception {
// 发送的数据
String str = null;
Scanner sc = new Scanner(System.in);
System.out.println("请输入需要传递的信息 : ");
// 获取输入的数据
str = sc.nextLine();
while (str != null ) {
// 字节数字输出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
// 写出数据到baos
dos.writeUTF(str);
// 把baos转换为字节数组
byte[] buf = baos.toByteArray();
// 发送数据,大小限制是64K,绑定地址
DatagramPacket dp = new DatagramPacket(buf, buf.length,
new InetSocketAddress("127.0.0.1", 10000));
// 发送,需要通过电脑中一个端口发送出去
DatagramSocket ds = new DatagramSocket(9999);
// DatagramPacket 数据包
// DatagramSocket 通信
ds.send(dp);
ds.close();
// 如果是exit 则退出客户端
if (str.equalsIgnoreCase("exit")) {
break;
}
System.out.println("请输入需要传递的信息 : ");
// 获取输入的数据
str = sc.nextLine();
}
2. 正则表达式
- \ : 转义符(java中写两个)
- 字符取值范围
- [abc] : 表示可能是a可能是b也可能是c
- [^abc] : 表示不是a,b,c中任意一个
- [0-9] : 表示是0到9任意数字
- [a-zA-Z] : 表示是大小写字母
- 简洁字符表示
- . : 匹配任意字符
- \d : 表示数字,等于 [0-9]
- \D : 非数字,等于 [^0-9]
- \s : 表示由空字符组成,等于 [ \t\n\r\x\f]
- \S : 表示由非空字符组成,等于 [^\s]
- \w : 表示字母,数字,下划线,等于 [a-zA-Z0-9_]
- \W : 表示非字母,数字,下划线
- 数量表达式
- ? : 表示出现0次或1次
- +: 表示出现1次或多次
- *: 表示出现任意次
- {n} : 表示出现n次
- {n,m} : 表示出现n到m次
- {n,} : 表示出现n次或n次以上
- 逻辑相关 :
- XY : 表示X后面跟着Y
- X|Y : 表示X或Y food|fa 匹配food或者fa
- (food|f) | a
- ^ : 表示以什么开头
- $ : 表示以什么结尾
- 在java.util.regex下,有三个正则表达式相关的类
- PatternSyntaxException : 正则表达式异常类
- Pattern : 正则表达式类,只能做简单操作
- Matcher : 支持强大的正则表达式匹配操作
- 实际操作中,有时候也是直接使用String中的方法,比如,分割,替换,验证
- boolean matches(String regex) 验证
- String[] split(String regex) 分割
- String replaceAll(String regex,String replacement) 替换
全词匹配
String str = "123456";
String regex = "\\d{6}";
//全词匹配,匹配成功返回true
System.out.println(Pattern.matches(regex, str));
2.1 Matcher
// 注意 ! 一个matcher对象,和相应的 find/matches/lookingAt 是配对的,
// 不要一起使用同一个matcher对象
// 如果一定要连用,必须重新打开matcher就可以
// 调用相同方法是可以连用的,比如调用多次find方法
Matcher.matches():对整个字符串进行匹配,只有整个字符串都匹配了才返回true
Matcher.lookingAt():对前面的字符串进行匹配,只有匹配到的字符串在最前面才返回true
Matcher.find():对字符串进行匹配,匹配到的字符串可以在任何位置
- 匹配
String regexTel = "\\d{11}";
String tel = "13113113111a";
// 引擎对象
Pattern pattern = Pattern.compile(regexTel);
// 匹配器对象
Matcher matcher = pattern.matcher(tel);
// 三种匹配方式
// 全词匹配 false
System.out.println(matcher.matches());
// 注意 ! 一个matcher对象,和相应的 find/matches/lookingAt 是配对的,
// 不要一起使用同一个matcher对象
// 如果一定要连用,必须重新打开matcher就可以
// 调用相同方法是可以连用的,比如调用多次find方法
// 重新创建匹配器对象
matcher = pattern.matcher(tel);
// 从前开始匹配
System.out.println(matcher.lookingAt());
matcher = pattern.matcher(tel);
// 任意位置
System.out.println(matcher.find());
- 提取
// 提取
public static void test02(){
String regexTel = "((.{2,3})的电话是)(\\d{11})";
String tel = "张三的电话是13113113111李小四的电话是15115115111";
// 引擎对象
Pattern pattern = Pattern.compile(regexTel);
// 匹配器对象
Matcher matcher = pattern.matcher(tel);
// find和group连用 是可以提取数据的
// 可以使用() 进行分组,一个() 就是一组
// 也可以不分组,不分组 就获取匹配到的数据,不能截取数据中的某一部分
// find匹配,如果字符串中有多个符合条件的数据,匹配到第一个就停止
// 想要获取下一个匹配的数据,就要再次调用find方法即可
while (matcher.find()) {
// 0 和无参 是获取匹配到的数据
// 1 就是第一组 2 就是第二组
System.out.println(matcher.group(2) +" : "+matcher.group(3));
// 匹配元素的起始索引
// System.out.println(matcher.start());
// 匹配元素的结束索引
// System.out.println(matcher.end());
}
}
- 去重
String str = "我我我我我我我我,,,,,,爱,,爱爱你,,你,你,你,你,你你你,个个个,,锤子";
//去除所有逗号
str = str.replaceAll(",", "");
System.out.println(str);
//取任意相同字符为一组
String regex = "(.)\\1*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
//将第一组遍历即为任意字符组的第一个字符
while(matcher.find()){
System.out.println(matcher.group(1));
}
//$1相当于group(1)
str = str.replaceAll(regex, "$1");
System.out.println(str);