epoll+线程池 封装

dwsocket.h #pragma once #include <string> #include <sys/epoll.h> #include <pthread.h> #include<condition_variable> #include <queue> #include<stdlib.h> namespace dw { using namespace std; class Addr { public: uint16_t port; string ip; public: Addr(string ip, uint16_t port); Addr(); ~Addr(); friend ostream& operator<<(ostream &out, const Addr &addr); private: }; class Socket { public: int socketFd; public: Socket(); ~Socket(); int read(void *data); private: }; typedef void(*ServerSocketCallBack)(Socket*); /* * 服务端Socket 完全异步 */ class ServerSocket { public: Addr *addr = NULL; int maxListenNum = 128;//最大监听数,libevent也是128 int epollSize = 65535;//epoll 的最大监听数 int maxEvents = 1024; int maxThread = 1; //最大线程数(socket开启时,会会根据cpu核心数,重新初始化该值) ServerSocketCallBack callBack = NULL; public: ServerSocket(uint16_t port); ~ServerSocket(); int start(); private: int socketfd = -1; int epollfd = -1; epoll_event* events; int *threadArry = NULL; queue<int> taskQueue; //任务队列 mutex taskQueueLock; //任务队列锁,防止两个线程读取同一个socket private: void initAddr(uint16_t port); int initSocket(); int initEpoll(); void setNonBlock(int fd); //设置非阻塞socket void initMaxThread(); void loopWait(); void addSocketFd(int fd); int initThreadPool(); //初始化线程池 static void * threadMain(void* arg);//线程主函数 }; } Addr.cpp ...

Go 笔记

package main import ( "fmt" "math/rand" "runtime" "strconv" "time" ) //import . "fmt" 这种导入方式 调用函数无需通过包名 //给包起别名 //import io "fmt" //忽略此包 //import _ "fmt" import ( "os" ) func main1() { a1() a2() a3() //a4() a5() a6() aif() aswitch() afor() arang() agoto() } //定义变量 func a1() { //声明变量,声明的变量必须要使用 var a int a = 10 var b, c int fmt.Println("a == ", a, b, c) //自动推到类型,必须初始化,通过初始化确定类型 d := 30 //打印变量类型 fmt.Printf("变量类型: %T\n", d) } func a2() { //多重初始化 a, b, c := 10, 20, 30 fmt.Printf("a = %d,b = %d,c = %d\n", a, b, c) //交换变量 a, b = b, a fmt.Printf("a = %d,b = %d,c = %d\n", a, b, c) //匿名变量,丢弃数据不处理,匿名变量配合函数返回值使用 var tmp int tmp, _ = a, b fmt.Printf("a = %d, tmp = %d\n", a, tmp) } func a3() { //常量 const a int = 10 fmt.Println(a) var b int var c float64 b, c = 10, 3.14 fmt.Printf("b = %d c = %f\n", b, c) //iota 常量自动生成器,每隔一行自动累加1,同一行,值一样 //iote 给常量赋值使用 const ( d = iota e, f = iota, iota ) fmt.Printf("d = %d, e = %d,f = %d\n", d, e, f) const ( n1 = iota n2 n3 ) fmt.Printf("n1 = %d, n2 = %d,n2 = %d\n", n1, n2, n2) //iote 遇到 const重置为0 const g = iota fmt.Println(g) } func a4() { //输入 var a int fmt.Println("请输入a变量") //阻塞等待用户输入 fmt.Scanf("%d", &a) fmt.Println("a = ", a) fmt.Println("请再次输入a变量") fmt.Scan(&a) fmt.Println("a = ", a) afor() } func a5() { //类型转换 //bool 不能转换成整型,整型也不能转换成bool类型,这种不能转换的类型叫不兼容类型 var flag bool = true fmt.Println(flag) var ch byte = 'a' var t int t = int(ch) fmt.Println(t) } func a6() { //类型别名 type bigint int64 var a bigint a = 10 fmt.Printf("%T", a) type ( long int64 char byte ) } func aif() { s := 'a' if s == 'a' { fmt.Println("满足条件") } else { fmt.Println("else") } //if 和初始化语句一起使用 if a := 10; a == 10 { fmt.Println("if 和初始化语句一起使用") } } func aswitch() { // 默认包含 break ,关键字 fallthrough 用于case穿透 num := 1 switch num { case 1: fmt.Println("1") fallthrough case 2: fmt.Println("2") case 3: fmt.Println("3") default: fmt.Println("default") } //和if一样支持初始化语句 switch num1 := 1; num1 { case 1: fmt.Println("1") fallthrough case 2: fmt.Println("2") case 3: fmt.Println("3") default: fmt.Println("default") } //case后面可以写条件 scorc := 85 switch { case scorc > 85: fmt.Println("优秀") case scorc <= 85: fmt.Println("一般") } //可以写多个 switch scorc { case 1, 2, 3: fmt.Println("1,2,3") case 5: fmt.Println("5") } } func afor() { sum := 0 for i := 0; i <= 100; i++ { sum += i } fmt.Println(sum) //死循环 for { fmt.Println("死循环") break } } func arang() { //迭代 str := "abc" for i, data := range str { fmt.Println(i, " ", data) } //第二个返回值默认丢弃 for i := range str { fmt.Println(i, ) } } func agoto() { //goto 可以用在任何地方,但是不能跨函数使用 goto End //goto 后面跟一个标签,标签名称,是自定义的 fmt.Println("aaa") End: fmt.Println("bbb") } //函数,不能重载 func afunc(a int, b int) { } func bfunc(a, b int) { } //不定参数,参数数量不确定 func cfunc(a ...int) { for i := 0; i < len(a); i++ { } for i, data := range a { fmt.Println(i, " ", data) } } //不定参数调用 func dfunc(a ...int) { cfunc(a...) //从初始位置到第二个传递到后面 cfunc(a[:2]...) //从第二个位置开始,后面的参数传递过去 cfunc(a[2:]...) } //一个返回值 func efunc() int { return 0 } //给返回值起一个名称,go 推荐写法 func ffunc() (test int) { return 0; } //直接给返回值赋值,然后直接返回 func gfunc() (res int) { res = 0 return } //返回多个值,go 官方推荐 func hfunc() (a int, b int, c int) { return 0, 0, 0 } //函数权限,函数首字母小写 函数为private函数,函数首字母大写为public //函数类型 type FuncType func(int, int) int func add(a int, b int) int { return a + b } func afunctype() { var a FuncType a = add sum := a(1, 2) fmt.Println(sum) } //匿名函数 func funca() { f1 := func() { } f1() //匿名函数调用 func() { }(); } //闭包中使用的参数不销毁 func funcb() func() int { var x int x++ return func() int { return x * x } } //闭包函数调用 func funcc() { f := funcb() fmt.Println(f()) fmt.Println(f()) fmt.Println(f()) } //defer 关键字,延迟调用 func funcd() { //不论中间发生什么错误,defer都能被调用,多个defer时 先声明的后执行 defer fmt.Println("结束时执行") fmt.Println("函数中") } //获取命令行参数 func main2() { list := os.Args fmt.Println(len(list)) } //导入包后 会先执行包中 init() 函数 func main3() { //指针,指针没有赋值值为nil var p *int var a int = 10 p = &a fmt.Println(*p) //指针赋值 var p1 *int p1 = new(int) fmt.Println(*p1) } func main4() { //数组,数组的元素个数必须是常量 var ids [10]int for i, data := range ids { fmt.Println("i=", i, " data=", data) } //初始化 var array [5]int = [5]int{1, 2, 3, 4} for i, data := range array { fmt.Println("i=", i, " data=", data) } //指定下标初始化 a1 := [5]int{2: 2, 4: 4} fmt.Println(a1) //数组比较 b1 := [3]int{1, 2, 3} b2 := [3]int{1, 2} if b1 == b2 { fmt.Println("数组相同") } else { fmt.Println("数组不相同") } //数组作为参数传递时,会将数组拷贝一份传递过去,所以需要改变数组中的值的时候,传递指针 arraytest(&a1) } func arraytest(p *[5]int) { fmt.Println(*p) } func main5() { //随机数 //1.设置种子,种子一样,每次产生的随机数都一样 rand.Seed(111); for i := 0; i < 10; i++ { ra := rand.Int(); fmt.Println(ra) } //限制随机数范围 for i := 0; i < 10; i++ { ra := rand.Intn(100); fmt.Println(ra) } } func main6() { //切片,切片和数组的区别就是数组声明时要指定长度,切片不需要指定长度 array := [...]int{1, 2, 3, 4, 5, 6} //三个参数, 起点,终点,容量 slice := array[1:3:4] fmt.Println(slice) //创建切片 //借助make函数,参数 切片类型,长度,容量,容量可以不写,不指定时和长度一样 s := make([]int, 5, 10) fmt.Println(s) //复制操作 s1 := array[:] fmt.Println(s1) //切片任然指向原来的数组,改变值之后,原先切片也会被改变 //添加元素 s = append(s, 1); fmt.Println(s) //复制 src := []int{1, 2} res := []int{1, 1, 1, 1} copy(res, src) fmt.Println(res) } func main7() { //map var m1 map[int]string fmt.Println(m1) m2 := make(map[int]string) m2[1] = "aaa" fmt.Println(m2) //指定长度,会自动扩容 m3 := make(map[int]string, 10) fmt.Println(m3) //初始化 m4 := map[int]string{1: "1", 2: "2"} fmt.Println(m4) //遍历 for key, val := range m4 { fmt.Println("key = ", key, " val = ", val) } //判断值是否存在 val, ok := m4[1] if ok { fmt.Println(val) } else { fmt.Println("key 不存在") } //删除指定key delete(m4, 1) fmt.Println(m4) } type User struct { id int name string sex byte age int } type Student struct { User num int } func main8() { //结构体 var user User = User{}; fmt.Println(user) //初始化 var user1 User = User{1, "姓名", 'm', 10}; fmt.Println(user1) var student Student = Student{User{1, "姓名", 'm', 10}, 1} fmt.Println(student) //初始化指定成员 var user2 User = User{name: "a"}; fmt.Println(user2) //操作参数 user2.id = 5 fmt.Println(user2) //比较 if user1 == user2 { fmt.Println("相等") } else { fmt.Println("不相等") } } //为结构体绑定函数,这里的接受者不能是指针 func (me User) setAge(age int) { me.age = age; } func (me *User) setAge1(age int) { me.age = age; } func main9() { a := make([]interface{}, 3) a[0] = 1 a[1] = "aaa" a[2] = 'c' if val, ok := a[0].(int); ok { fmt.Println(val) } else { fmt.Println("类型不符合") } } func main10() { //异常操作 //中断函数 //panic("aaaaaaaaaaaa) defer func() { //用来恢复错误 //recover() //打印错误信息 fmt.Println(recover()) }() } func main11() { //字符串操作 bytes := make([]byte, 0, 1024) bytes = strconv.AppendBool(bytes, true) //追加整数,以10进制方式追加 bytes = strconv.AppendInt(bytes, 12, 10) bytes = strconv.AppendBool(bytes, true) //其他类型转换为字符串 var str string str = strconv.FormatBool(false) str = strconv.Itoa(1111) fmt.Println(str) // 字符串转其他类型 flag, _ := strconv.ParseBool("true") fmt.Println(flag) } func main12() { //文件 //设备文件 屏幕啊,键盘啊...... //磁盘文件 //标准设备文件,默认已经打开,用户可以直接使用 os.Stdout.WriteString("aaaaaaaa") } func newTask() { for { fmt.Println("newTask") time.Sleep(time.Second) } } //数据同步 var ch = make(chan int) func main13() { //创建一个协成,如果主线程退出,协成也会退出 go newTask() //让出时间片,先让别的协成先执行,等其他协成执行完,在回来执行此协成 runtime.Gosched() //设置使用cpu的最大核心数,返回之前使用的最大数 n := runtime.GOMAXPROCS(1) fmt.Println(n) //终止所在协成 runtime.Goexit() //数据给管道 ch <- 66 //从管道取数据,如果管道没有数据就会阻塞 var a = <-ch fmt.Println(a) //关闭管道,管道关闭之后数据不可写入,但是任然可以读取 close(ch) ch1 := make(chan int) //双向管道能隐式转换成单方向的管道 var writeCh chan<- int = ch1 //只能写,不能读 var readCh <-chan int = ch1 //只能读,不能写 writeCh <- 1 var aint = <-readCh fmt.Println(aint) for { fmt.Println("main") time.Sleep(time.Second) } } func main() { ch := make(chan int) //监听管道流动方向,每一个case都是一个io操作 select { case <-ch: case ch <- 1: default: } }

Go 时间日期格式化

坑 go规定格式化必须用指定的时间点 formatStr := "2006-01-02 15:04:05" fmt.Println(time.Now().Format(formatStr))

html select

获取当前选中值的自定义属性 $('#id').find("option:selected").attr('price');

Http 跨域(Cors) 详解

1.构成跨域的条件(满足下方任意一个条件则构成跨域) domain不同(域名或者ip不同) 端口不同 协议不同(http/https) 给大家展示一个请求头和响应头,这是满足跨域的 请求头 POST http://127.0.0.1:10030/user/login HTTP/1.1 Host: 127.0.0.1:10030 Connection: keep-alive Content-Length: 33 Pragma: no-cache Cache-Control: no-cache Accept: application/json, text/plain, */* Origin: http://localhost:8080 User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1 Content-Type: application/x-www-form-urlencoded Referer: http://localhost:8080/ Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7 Cookie: cna=CKV9Ew45tVYCAX1SFKx2d19k; _uab_collina=152896489958250435552525; _umdata=65F7F3A2F63DF020E1473F196945E27DBC990F7BBC00081CD2D29B2B4AD9F1FCC05972083687D762CD43AD3E795C914CD2FEBFBF6205958F64E60BC7B372D87F; Hm_lvt_31d8fd22bdec2e7ab9e5855741f0fac1=1541048271,1541503268,1542598403,1543222019; SESSION=NDllODZlMWQtODk5ZC00MDg3LThiN2ItNGM0MTRlMjZlOTFm phone=15555555555&password=111111 响应头 HTTP/1.1 200 Vary: Origin Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Access-Control-Allow-Origin: http://localhost:8080 Access-Control-Allow-Credentials: true Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Tue, 01-Jan-2019 06:44:30 GMT Content-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked Date: Wed, 02 Jan 2019 06:44:30 GMT 103 {"data":{"id":2,"name":null,"nickName":"15555555555","email":null} 0 详解 首先请求头中需要设置,这个是设置跨域的的协议,domain 和端口,也就是浏览器地址的栏的根路径 ...

HttpClient 使用

1.导入jar包 <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.5</version> </dependency> post请求 public static String send(Map<String, String> textParams, Map<String, byte[]> byteParams) throws IOException { CloseableHttpClient httpClient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost(Constant.taobaoUrl); HttpEntity content = getContent(textParams, byteParams); httpPost.setEntity(content); CloseableHttpResponse response = httpClient.execute(httpPost); HttpEntity responseEntity = response.getEntity(); String result = EntityUtils.toString(responseEntity, Charset.forName("UTF-8")); response.close(); return result; } 发送自定义数据 String data = "数据"; CloseableHttpClient httpClient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost("https://dh.shiwan123.com/udid/sw/mqq"); //设置发送数据 ByteArrayInputStream in = new ByteArrayInputStream(data.getBytes()); InputStreamEntity reqEntity = new InputStreamEntity(in); httpPost.setEntity(reqEntity); CloseableHttpResponse response = httpClient.execute(httpPost); HttpEntity responseEntity = response.getEntity(); String result = EntityUtils.toString(responseEntity, Charset.forName("UTF-8")); response.close(); Header location = response.getFirstHeader("Location");

idea springboot 打jar包

操作步骤 步骤一 file->Project Structure->Artifacts 步骤二 点击左上角的绿色加号 + Jar->From modules with…. 步骤3 Main Class 选择对应的项目主函数 Jar files from libraries 选择 copy to the output directory and link via manifest Directory for META-INF/MANIFEST.MF 选择 项目的 resources文件夹 然后 点击OK 即可 软件点击 菜单栏的 Build->Build Artifacts 选 All Artifacts 构建所有 或者选择需要构建的jar包 问题 如果出现 alread exists in VFS 的错误 请删除 Resourcse文件夹下面的 META-INF 文件夹 运行时如果出现异常 ClassLoadFond 错误 原因的 resources/META-INF/MANIFEST.MF 中缺少相对应的jar包 解决办法 一 删除 resources/META-INF 文件夹 和对应的 Artifact 重新建立 ...

IDEA 创建聚合项目

建立项目 1.建立父项目 (1)建立一个maven项目 不选择则任何模板创建 (2)删掉项目中的src文件夹 2.项目中建立对应的模块项目即可

ifconfig 命令不存在

command not ifconfig 解决办法 centos sudo yum install net-tools

java 交集 并集 差集

public static void main(String[] args) { Set<Integer> result = new HashSet<Integer>(); Set<Integer> set1 = new HashSet<Integer>(){{ add(1); add(3); add(5); }}; Set<Integer> set2 = new HashSet<Integer>(){{ add(1); add(2); add(3); }}; result.clear(); result.addAll(set1); result.retainAll(set2); System.out.println("交集:"+result); result.clear(); result.addAll(set1); result.removeAll(set2); System.out.println("差集:"+result); result.clear(); result.addAll(set1); result.addAll(set2); System.out.println("并集:"+result); //差集 List<Integer> list = new ArrayList<>(); List<Integer> list2 = new ArrayList<>(); list.removeAll(list2); }