基于C++从0到1手写Linux高性能网络编程框架-15章

荀勗
• 阅读 160

参考资料地址1:https://pan.baidu.com/s/1i8FuLluEUV3BJFphjKWvhQ 提取码:zvet 参考资料地址2:https://pan.baidu.com/s/1MgD4BdeD6V6HfXkoMAZ5Hw 提取码:l5t4

网络编程概述 管道(父子进程)、消息队列(内核经营消息队列)、共享内存(创建一个空间)、信号(通过pid号通信)、信号量(对临界资源,共享内存做P、V控制) 。 特点:依赖于Linux内核 A B两个通信基于内核。缺陷:无法多机通信 (不适用与两台不同的电脑)

TCP和UDP对比: TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前 不需 要建立连接 TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付 TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等) 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信 TCP首部开销20字节;UDP的首部开销小,只有8个字节 TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

传统的进程间通信借助内核提供的IPC机制进行,但是只能限于本机通信。若要跨机通信,就必须使用网络通信,这就需要用到内核提供给用户的socket API函数库。 2.1 网络字节序 大端字节序:也叫高端字节序(网络字节序),是高端地址存放低位数据,低端地址存放高位数据 小端字节序:也叫低端字节序,是低地址存放低位数据,高地址存放高位数据。 在application.yml文件中,填入SaToken的配置信息,如下: sa-token: #HTTP请求头中哪个属性用来上传令牌 token-name: token #过期时间(秒),设置为30天 timeout: 2592000 #临时有效期,设置为3天 activity-timeout: 259200 #不允许相同账号同时在线,新登陆的账号会挤掉原来登陆的账号 allow-concurrent-login: false #在多人登陆相同账号的时候,是否使用相同的Token is-share: false token-style: uuid #是否读取Cookie中的令牌 isReadCookie: false #同端互斥 isConcurrent: false #SaToken缓存令牌用其他的逻辑库,避免业务数据和令牌数据共用相同的Redis逻辑库 alone-redis: database: 1 host: localhost port: 6379 password: abc123456 timeout: 10s lettuce: pool: # 连接池最大连接数 max-active: 200 # 连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: 10s # 连接池中的最大空闲连接 max-idle: 16 # 连接池中的最小空闲连接 min-idle: 8 Java语言允许我们自己封装异常类,我们可以自定义各种异常类,比如每种业务一个异常类,或者每个模块一个异常类。我这里不想做的那么复杂,不如我们创建一个通用的异常类,用来封装与业务有关的异常信息。

在com.example.his.api.exception包中,创建HisException.java类。 package com.example.his.api.exception; import lombok.Data;

@Data public class HisException extends RuntimeException { private String msg; private int code = 500;

public HisException(Exception e) {
    super(e);
    this.msg = "执行异常";
}

public HisException(String msg) {
    super(msg);
    this.msg = msg;
}

public HisException(String msg, Throwable e) {
    super(msg, e);
    this.msg = msg;
}

public HisException(String msg, int code) {
    super(msg);
    this.msg = msg;
    this.code = code;
}

public HisException(String msg, int code, Throwable e) {
    super(msg, e);
    this.msg = msg;
    this.code = code;
}

} SpringBoot提供了全局处理异常的技术,只要我们给某个Java类用上@RestControllerAdvice注解,这个类就能捕获SpringBoot项目中所有的异常,然后统一处理(精简异常信息)再返回给前端项目。 在com.example.his.api.config包中,创建ExceptionAdvice.java类。 package com.example.his.api.config;

import cn.dev33.satoken.exception.NotLoginException; import cn.felord.payment.PayException; import cn.hutool.json.JSONObject; import com.example.his.api.exception.HisException; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.BindException; import org.springframework.http.HttpStatus; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.multipart.support.MissingServletRequestPartException;

@Slf4j @RestControllerAdvice public class ExceptionAdvice { /* * 捕获异常,并且返回500状态码 */ @ResponseBody @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(Exception.class) public String exceptionHandler(Exception e) { JSONObject json = new JSONObject(); if (e instanceof HttpMessageNotReadableException) { HttpMessageNotReadableException exception = (HttpMessageNotReadableException) e; log.error("error", exception); json.set("error", "请求未提交数据或者数据有误"); } else if (e instanceof MissingServletRequestPartException) { MissingServletRequestPartException exception = (MissingServletRequestPartException) e; log.error("error", exception); json.set("error", "请求提交数据错误"); } else if (e instanceof HttpRequestMethodNotSupportedException) { HttpRequestMethodNotSupportedException exception = (HttpRequestMethodNotSupportedException) e; log.error("error", exception); json.set("error", "HTTP请求方法类型错误"); } //Web方法参数数据类型转换异常,比如String[]数组类型的参数,你上传的数据却是String类型 else if (e instanceof BindException) { BindException exception = (BindException) e; String defaultMessage = exception.getFieldError().getDefaultMessage(); log.error(defaultMessage, exception); json.set("error", defaultMessage); } //没有通过后端验证产生的异常 else if (e instanceof MethodArgumentNotValidException) { MethodArgumentNotValidException exception = (MethodArgumentNotValidException) e; json.set("error", exception.getBindingResult().getFieldError().getDefaultMessage()); } //处理业务异常 else if (e instanceof HisException) { log.error("执行异常", e); HisException exception = (HisException) e; json.set("error", exception.getMsg()); } //微信支付异常 else if (e instanceof PayException) { PayException exception = (PayException) e; log.error("微信支付异常", exception); json.set("error", "微信支付异常"); } //处理其余的异常 else { log.error("执行异常", e); json.set("error", "执行异常"); } return json.toString(); }

/*
 * 捕获异常,并且返回401状态码
 */
@ResponseBody
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(NotLoginException.class)
public String unLoginHandler(Exception e) {
    JSONObject json = new JSONObject();
    json.set("error", e.getMessage());
    return json.toString();
}

} 因为Controller类用上@RestController注解之后,Web方法返回的对象会被自动转换成JSON对象,所以我们只需要声明一个封装类,让所有Web方法返回这个封装类的对象即可。除了公共属性之外,不同的Web方法要返回的业务数据也不尽相同,所以选择动态的结构才是最佳的方案,恰好HashMap允许我们随便添加数据,那就选择HashMap作为父类吧。在com.example.his.api.common包中,创建R.java类。 package com.example.his.api.common;

import org.apache.http.HttpStatus; import java.util.HashMap; import java.util.Map;

public class R extends HashMap<String, Object> { public R() { //默认创建的R对象中包含了公共的属性 put("code", HttpStatus.SC_OK); put("msg", "success"); }

/*
 * 覆盖继承的put函数,添加Key-Value数据
 */
public R put(String key, Object value) {
    super.put(key, value);
    //把自己返回,用于链式调用
    return this;
}

public static R ok() {
    return new R();
}

public static R ok(String msg) {
    R r = new R();
    r.put("msg", msg);
    return r;
}

public static R ok(Map<String, Object> map) {
    R r = new R();
    r.putAll(map);
    return r;
}

public static R error(int code, String msg) {
    R r = new R();
    r.put("code", code);
    r.put("msg", msg);
    return r;
}

public static R error(String msg) {
    return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
}

public static R error() {
    return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
}

}

点赞
收藏
评论区
推荐文章
赵颜 赵颜
5个月前
SpringBoot 3 + Flutter3 实战低代码运营管理-10章
参考资料1:https://pan.baidu.com/s/1sE93jgGx3QwuVbbKtGvQ提取码:2nli参考资料2:https://pan.baidu.com/s/1xXEFkvYj0ZX2l2zZShA7w提取码:d2nw技术人员唯有多领域
荀勗 荀勗
5个月前
高性能多级网关与多级缓存架构落地实战(完结+附电子书)
参考资料地址1:https://pan.baidu.com/s/12w0TT26aywnoIcogPg8Uw提取码:uzf4参考资料地址2:https://share.weiyun.com/SNltUNLW密码:zi3dc7什么是网关?网关(Gateway
赵颜 赵颜
4个月前
[16章]SpringBoot2 仿B站高性能前端+后端项目(2023新版)
资料地址1:https://pan.baidu.com/s/1cxQDKIi7iu1mGmjRr9a0Mw提取码:tz5s资料地址2:https://pan.baidu.com/s/1DjmuC6Id4oUCNVbxfgcMg提取码:qtf3今天给大家讲讲
赵颜 赵颜
4个月前
[15章]深入学习小程序框架底层原理,培养双线程思维
学习地址1:https://pan.baidu.com/s/1ridzu0mrj1vrfT07fdReuw提取码:3zd2学习地址2:https://pan.baidu.com/s/1SChnJCGf03sybLfyAnkCA提取码:c862前端高手特训从
吉太 吉太
4个月前
[2023新版16章]SpringBoot+Vue3 项目实战,打造企业级在线办公系统
参考资料地址1:https://pan.baidu.com/s/1ZJGS0SA9pIUr76VUXioNSg提取码:95bd参考资料地址2:https://share.weiyun.com/jVSDdcBU密码:cruqf9SpringBootVue3
赵嬷嬷 赵嬷嬷
4个月前
[完结10章]Vue3+Pinia+Vite+TS 还原高性能外卖APP项目
参考资料地址1:https://pan.baidu.com/s/1u0uNBMkOA2NRk3N6myb4Zg提取码:tnlt参考资料地址2:https://share.weiyun.com/Wjw3QpeQ密码:gxrfcwVue3带来的改变,除了其自身
双寿 双寿
3个月前
慕课甄选-2024年Flutter零基础极速入门到进阶实战[16章]
参考资料地址1:https://pan.baidu.com/s/1j35W30a7JQAGTV2rYgxRNA提取码:5o3h参考资料地址2:https://pan.baidu.com/s/1Iwj10AL7jdum19WQz1jdA提取码:0n8xFlu
鲍二家的 鲍二家的
1个月前
AI Agent智能应用从0到1定制开发(12章)
学习地址1:https://pan.baidu.com/s/1ccnoXsPCUg4eP5rSrD0UA提取码:o0mu学习地址2:https://pan.baidu.com/s/1JYJ6dMkwgx0XWQnCM6Q0A提取码:2m68AIAgent已
双寿 双寿
1个月前
[20章+电子书]真实高质量低代码商业项目,前端/后端/运维/管理系统
参考资料1:https://pan.baidu.com/s/1VClcoYhOBOLPH487k78Lw提取码:dmu0参考资料2:https://pan.baidu.com/s/1zgrv2qJMaEV5yVwi4pThXg提取码:kzrl“LowCod
双寿 双寿
1个月前
音视频高手突围课--WebRTC企业级高性能后台服务实战(15章)
参考资料1:https://pan.baidu.com/s/1b4kcRMN6FHoHYCl3lJwrAw提取码:hgt6参考资料2:https://pan.baidu.com/s/1VrKcjKdz0qmVlufrwBtsQ提取码:tylx一、什么是We