wscml/
lib.rs

1//use std::fmt::format;
2use std::net::{SocketAddr,TcpListener,TcpStream,Shutdown};
3use std::io::prelude::*;
4use std::fs;
5// use std::collections::HashMap;
6use std::str;
7use std::time::SystemTime;
8use chrono::{DateTime, Utc};
9use std::io as other_io;
10
11use std::fs::File;
12
13//以下线程部分引入
14use std::sync::{Arc,Mutex,mpsc};
15use std::thread;
16include!("thread.rs");
17
18//文件打开
19include!("func.rs");
20
21include!("pubmsg.rs");
22
23//文件打开
24include!("http.rs");
25include!("ws.rs");
26include!("tcp.rs");
27
28// let mut file = File::open("foo.txt")?;
29// let mut contents = String::new();
30// file.read_to_string(&mut contents)?;
31// assert_eq!(contents, "Hello, world!");
32
33//tokio
34
35use tokio::fs as tokiofs;
36use tokio::io::{self, AsyncReadExt};
37
38use tokio::time::{timeout,Duration};
39use tokio::net::{TcpListener as TokioTcpListener,TcpStream as TokioTcpStream,ToSocketAddrs};
40use tokio::io::{AsyncWriteExt};
41use std::net::SocketAddr as TokioSocketAddr;
42
43use tokio::time::Sleep;
44
45const BUF_NUM:usize = 1024;
46
47const HTVNUM:usize = b"HTTP/1.1".len();
48const HTV:&[u8;HTVNUM] = b"HTTP/1.1";
49const HTTPPDNUM:usize = b"Connection: keep-alive".len();
50const HTTPPD:&[u8;HTTPPDNUM] = b"Connection: keep-alive";
51const WSNUM:usize = b"Upgrade: websocket".len();
52const WS:&[u8;WSNUM] = b"Upgrade: websocket";
53const IPADDARRNUM:usize = 10;
54
55
56
57/// ipaddre ip和端口的映射
58/// 
59/// http_app_top
60/// ├ 路径路由方法
61/// ├ 上传方式方式
62/// ├ 传输信息
63/// ├ 成员数量
64/// 
65/// ipaddnum
66/// ip地址的个数 http_setbpost 增加
67/// 
68/// pool_num
69/// 线程个数
70/// 
71/// top_templ
72/// dow_templ 变量头尾
73/// 
74/// overtext 结束关键字
75/// 
76#[derive(Debug, Clone)] 
77pub struct CmlServer {
78    ipaddre: [&'static str;IPADDARRNUM],
79    http_app_top: [( &'static str, Func, ( [&'static str;30], [&'static str;4])); 300],
80    ipaddnum:usize,
81    pool_num:usize,
82    top_templ:String,
83    dow_templ:String,
84    overtext:String,
85}
86
87impl <'a >CmlServer {
88    /// 声明一个 web、websocket以及tcp服务。
89    /// 
90    /// # Examples
91    /// 
92    /// 绑定一个ip和端口"0.0.0.0:8000" 到当前服务,并且开启10个工作线程。
93    /// 
94    /// let mut cml = CmlServer::new("0.0.0.0:8000",10);
95    /// 
96    /// 设置ip以及post
97    /// pnum 设置多个线程数
98    pub fn new(ipadd:&'static str,pnum:usize) -> CmlServer  {
99        let mut ipaddarr:[&str;10] = ["";IPADDARRNUM];
100        ipaddarr[0] = ipadd;
101       
102        CmlServer{
103            ipaddre: ipaddarr,
104            http_app_top: [( "", ne, ( ["";30], ["";4])); 300],
105            ipaddnum:   1,
106            pool_num :  pnum,
107            top_templ:  "".to_string(),
108            dow_templ:  "".to_string(),
109            overtext:   "over".to_string(),
110        }
111    }
112
113    /// templ 中的string是为了在模板中识别变量替换文本用的关键字
114    /// 
115    /// 例如 模板中的变量为 {$pname}
116    /// 
117    /// 将用 templ("{$".to_string(),"}".to_string()); 来处理这变量个分割数据方法
118    /// 
119    pub fn templ(&'a mut self , top_template: String, down_template:String) {
120        self.top_templ = top_template;
121        self.dow_templ = down_template;
122    }
123
124
125    /// http server 设置目录和内容地址
126    /// 
127    /// # Examples
128    /// 
129    /// CmlServer.http_route( "/sleep?user&name", sleep,"get|post");
130    /// 
131    /// 设置目录地址。
132    /// 
133    /// 主要是三个问题 一个是方法 二是地址
134    /// 
135    pub fn http_route (
136        &'a mut self, 
137        pathdata: &'static str, 
138        html_fun: Func,
139        port: &'static str,
140    ) {
141        // let a = Html_fu(htmlfunc,"url路径");
142        let pathsplit: Vec<&str> = pathdata.split("?").collect();
143        let path = pathsplit[0];
144        let webdata = match pathsplit.len() {
145            1 => "",
146            _=>pathsplit[1],
147        };
148
149        let mut app_top = self.http_app_top;
150        let webdata_split :Vec<&str> = webdata.split("&").collect();
151        let web_port:Vec<&str> = port.split("|").collect();
152        let webport: [&str; 4];
153
154        webport = match web_port.len() {
155            4 => {
156                [web_port[0],web_port[1],web_port[2],web_port[3]]
157            },
158            3 => {
159                [web_port[0],web_port[1],web_port[2],""]
160            },
161            2 => {
162                [web_port[0],web_port[1],"",""]
163            },
164            1 => {
165                if web_port[0] =="" {
166                    ["get","","",""]
167                }else{
168                    [web_port[0],"","",""]
169                }
170            },
171            _ => {
172                ["get","","",""]
173            }
174        };
175
176        let mut webdata_z = ["";30];
177        
178        for (ind,val) in webdata_split.iter().enumerate() {
179            webdata_z[ind] = val;//webdata_split[ind];
180        }
181
182        'tzcp: for int in 0..app_top.len() {
183            if app_top[int].0 == "" {
184                app_top[int] = (path,html_fun,(webdata_z,webport));
185                let pat = path.clone();
186                if pat != "/" {
187                    let pat = pat.to_string() + "/";
188                    app_top[int+1] = (Box::leak(pat.into_boxed_str()),html_fun,(webdata_z,webport));
189                }
190                
191                break 'tzcp;
192            }
193        }
194        
195        self.http_app_top = app_top;
196    }
197
198    /// 处理数组到 socketaddr数组
199    fn ipaddthearr(&'a self,ipadd: &str) -> ([u8; 4], u16) {
200        let ipcl: Vec<&str> = ipadd.split_terminator(":").collect();
201        let ipcls: Vec<&str> = ipcl[0].split_terminator(".").collect();
202        let mut ipclz = [0;4];
203        for ins in 0..ipcls.len() {
204            ipclz[ins] = ipcls[ins].parse::<u8>().unwrap();
205        }
206        let a:([u8;4],u16) = (ipclz,ipcl[1].parse::<u16>().unwrap());
207        a
208    }
209
210    ///优雅的结束服务
211    /// 
212    /// # Examples
213    /// cml.over_text("over");
214    /// 
215    /// shell $ over 
216    /// 当shell中输入 over 后程序结束进程并关闭
217    /// 结束进程关闭程序。
218    /// 
219    /// 
220    pub fn over_text(&'a mut self,text:&str){
221        self.overtext = format!("{}\r\n",text);
222    }
223
224    /// 添加备用ip和端口
225    /// 
226    /// # Examples
227    /// 
228    /// cml.http_setbpost("0.0.0.0:8001");
229    /// 设置备用的ip和post。
230    /// 
231    pub fn http_setbpost(&'a mut self,inpost:&'static str){
232        let mut post = self.ipaddre.clone();
233        'tc: for inr in 0..post.len() {
234            if post[inr] == "" {
235                post[inr] = &inpost;
236                break 'tc;
237            }
238        }
239        self.ipaddnum += 1;
240        self.ipaddre = post;
241    }
242
243    /// 执行程序
244    /// 
245    ///  # Examples
246    /// 
247    /// cml.biud();
248    /// 执行监听和执行。
249    /// 
250    pub fn biud(&'a self){
251        if self.top_templ == "".to_string()
252        || self.dow_templ == "".to_string() {
253            println!("未设置模板关键字!");
254            return;
255        }
256        // if self.overtext == "" {
257        //     println!("未设置关闭关键字,默认关键字\"over\"! ");
258        //     return;
259        // }
260        if self.http_app_top.len() == 1 
261        || self.http_app_top[0].0 == "" {
262            println!("http_route 中没有反射数据! ");
263            return;
264        }
265        match self.initconfig() {
266            true => {
267
268            },
269            _ => {
270                println!("请查找相关配置!");
271                return ;
272            }
273        }
274
275        let ipaddres = self.ipaddre.clone();
276        let mut ipaddarr = vec![SocketAddr::from(([0, 0, 0, 0], 0)); self.ipaddnum];
277        
278        for int in 0..ipaddres.len() {
279            if ipaddres[int] != "" {
280                ipaddarr[int] = SocketAddr::from(self.ipaddthearr(ipaddres[int]));
281            }
282        }
283
284        let listener = TcpListener::bind(&ipaddarr[..]);
285
286        if !listener.is_ok() {
287            println!("[Server] : Bind ip and port fail ... (监听端口失败)");
288            return;
289        }
290
291        cxdy(ipaddarr);
292
293        let pool:ThreadPool = ThreadPool::new(self.pool_num);
294
295        let listener:TcpListener = listener.unwrap();
296        
297
298        for stream in listener.incoming() {
299            
300            // struct 上面标记 #[derive(Clone)] 才能够使用clone功能
301            // 这里为什么需要clone呢?因为我们需要在下面把 self 传递到一个异步的代码块中。这意味着 handle_client 和 &mut self 的生命周期是相同的。但是这不不符预期,因为我们想在多个线程生运行 handle_client 以更好的性能。或者产生多个 handle_client 并将它们全部并行运行。如果对 self中的值 的引用存在于 handle_client 2 中,这就不可能了。所以需要将self拷贝出来。
302            let this = self.clone();
303            pool.execute(move || {
304                this.handle_client(stream.unwrap());
305            });
306            
307        }
308        
309        
310        println!("Shutting down(关闭).");
311    }
312
313    //消息处理 War thunder
314    fn handle_client(&'a self, mut stream: TcpStream){
315
316        let mut buffer:[u8; BUF_NUM] = [0; BUF_NUM];
317
318        let mut pd= false;
319
320        'a:loop {
321            stream.read(&mut buffer).unwrap();
322            let mut buf_n: u8 = 0;
323            buf_n = self.isservertype(buffer,buf_n);
324            println!("{}",String::from_utf8_lossy(&buffer[..]));
325            println!("type :{}",buf_n);
326            
327            match buf_n {
328                0 => {
329                    (stream,pd) = self.tcp_to_server(stream,buffer,pd);
330                    if pd == true {
331                        break 'a;
332                    }
333                },
334                2 => {
335                    self.http_to_server(stream,buffer);
336                    break 'a;
337                },
338                buf_n if buf_n == 3 => {
339                    (stream,pd) = self.websockserver( stream,buffer,pd);
340                    if pd == true {
341                        break 'a;
342                    }
343                },
344                _ => println!("over"),
345            }
346
347        }
348        println!(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>结束 等待下一次连接!\r\n\r\n\r\n");
349
350    }
351
352    /// 判断接受tcp信息的类型
353    /// 0 tcp
354    /// 
355    /// 
356    /// 1 只是标记http请求来源为http/1.1
357    /// 2 http
358    /// 3 websocket
359    /// 
360    /// 
361    fn isservertype(&'a self,buffer: [u8;BUF_NUM],mut n: u8) -> u8 {
362        let tcjc = [0;BUF_NUM];
363        if tcjc != buffer {
364            for i in 0..BUF_NUM {
365                let lll: [u8;HTVNUM] = [0;HTVNUM];
366                if i + HTVNUM < BUF_NUM{
367                    let splits = &buffer[i..(i+HTVNUM)];
368                    if  &splits == HTV
369                    &&  &splits != &lll{ 
370                        //println!("PBNUM:{:?},pbunm:{:?}",String::from_utf8_lossy(&splits[..]),&splits);
371                        if n == 0 {
372                            n = 1;
373                        }
374                    }
375                }
376    
377                let lll: [u8;HTTPPDNUM] = [0;HTTPPDNUM];
378                if  i + HTTPPDNUM <= BUF_NUM{
379                    let splits = &buffer[i..(i+HTTPPDNUM)];
380                    if  &splits == HTTPPD
381                    &&  &splits != &lll
382                    &&  (n == 0 || n == 1){
383                        n = 2;
384                    }
385                }
386    
387                let lll: [u8;WSNUM] = [0;WSNUM];
388                if  i + WSNUM <= BUF_NUM{
389                    let splits = &buffer[i..(i+WSNUM)];
390                    if  &splits == WS
391                    &&  &splits != &lll
392                    &&  (n == 0 || n == 1){
393                        n = 3;
394                    }
395                }
396                
397            }
398        }
399    
400        return n;
401    }
402
403    //待开发tcp服务器
404    fn tcp_to_server(&'a self, mut stream: TcpStream, buffer: [u8;BUF_NUM], mut a: bool) -> (TcpStream,bool) {
405
406        let mut n: i32 = 0;
407        let ns: i32 = 10000;
408        let tcpclose = b"tcpclose"; //tcp 关闭连接口令
409        let tcpbeat = b"tcpbeat"; //tcp 心跳请求
410
411        let mut dl: Textlist = Textlist::new();
412
413        let httptext = String::from_utf8_lossy(&buffer[..]);
414        println!("tcp msg:{}",httptext);
415    
416        let tcptextclose: &[u8] = &buffer[..tcpclose.len()];
417        let tcptextbeat: &[u8] = &buffer[..tcpbeat.len()];
418        let getuserip = stream.peer_addr().unwrap();
419        
420        if tcptextclose == tcpclose {//检测是否是关闭口令
421            let response:String = format!("你好!你正在向服务端请求关闭。");
422            stream.write(response.as_bytes()).unwrap();
423            stream.flush().unwrap();
424            println!("关闭连接");
425            stream.shutdown(Shutdown::Both).expect("shutdown call failed");//关闭客户连接
426            n = ns;
427        }else if tcptextbeat ==  tcpbeat {
428            n = 0;
429            let response:String = format!("与服务器心跳连接成功!");
430            stream.write(response.as_bytes()).unwrap();
431        } else {
432            n = 0;
433            let response: &[u8] = "无广播消息!".as_bytes();
434            
435            if !dl.is_empty() {
436                let response = dl.theone(0);
437                println!("qmsg:{:?}",response);
438            } else {
439                println!("qmsg is null!");
440            }
441            
442            dl.push(buffer);
443            
444            dl.printdl();
445            stream.write(response).unwrap();
446        }
447
448        if n >= ns{
449            println!("退出循环");
450            stream.shutdown(Shutdown::Both).expect("shutdown call failed");//关闭客户连接
451            println!("\n超出心跳时间,{}次问询后无响应。----{}-----\n\n\n",n,getuserip);
452            a = true;
453        }
454        
455        n += 1;
456        println!("\n----{}-----{}-----\n\n\n",getuserip,n);
457
458        (stream,a)
459    }
460
461    // http服务器
462    fn http_to_server(&'a self, mut stream:TcpStream, buffer: [u8;BUF_NUM]) {
463        let response = "HTTP/1.1 200 OK";
464        let notfound = "HTTP/1.1 404 NOT FOUND";
465        let httpcode:&str = " HTTP/1.1\r\n";
466        let httptop = ["GET","POST","PUT","DELETE"];
467        let uri:[(&str,Func,([&'static str;30],[&'static str;4]));300] = self.http_app_top;
468        let mut status_line: &str = "";
469        let mut filename: &str = "";
470        let mut rest_ype: String = String::from("");
471        let mut rest_ype_num: u8 = 0;
472        let mut aus:String;
473        let mut pzjg = false;
474        let mut fhtml:String = "".to_string();
475        
476        'httpt: for i in httptop {
477            let b:&[u8] = &i.to_string().into_bytes();
478            
479            if buffer.starts_with(b) {
480                for s in uri{
481                    
482                    if s.0 == "" {
483                        break 'httpt;
484                    }
485
486                    let topbu = if_split(&buffer, httpcode);
487                    let aansbool = wscmlsuffix(topbu,&s,i);
488                    let favicon:String = format!("{} {}favicon.ico",i,s.0);
489                    let afavicon:&Vec<u8> = &favicon.into_bytes();
490                    let jpg:String = format!("{} {}1.jpg",i,s.0);
491                    let afavjpg:&Vec<u8> = &jpg.into_bytes();
492
493                    // println!("文件内部:{:?}",topbuf[0]);
494                    (status_line,filename,rest_ype,rest_ype_num,pzjg,fhtml) = 
495                    if aansbool {
496                        aus = wscmlurl(&s);
497                        
498                        fhtml = wscmldata(self.top_templ.clone(),self.dow_templ.clone(),buffer,&s);
499
500                        (response, &aus[..],String::from("text/html; charset=UTF-8"),0,true,fhtml)
501                    } else if buffer.starts_with(afavicon) {
502                        (response, "h/favicon.ico",String::from("image/x-icon"),1,true,"".to_string())
503                    } else if buffer.starts_with(afavjpg) {
504                        (response, "h/1.jpg",String::from("image/jpeg"),2,true,"".to_string())
505                    } else {
506                        (notfound, "h/404.html",String::from("text/html; charset=UTF-8"),0,false,"".to_string())
507                    };
508    
509                    if pzjg == true {
510                        break 'httpt;
511                    }
512                }
513            }
514        }
515    
516        println!("这url地址:{:?} match:{:?}",filename,rest_ype_num);
517    
518        if filename != "" {
519            match rest_ype_num {
520                0 => {
521                    let mut contents:String = String::from("");
522                    if fhtml == "" {
523                        contents = fs::read_to_string(filename).unwrap();
524                    }else{
525                        contents = fhtml.to_string();
526                    }
527                    //let contents: String =  fs::read_to_string(filename).unwrap();
528
529                    let response: String = format!(
530                        "{}\r\nContent-Length: {}\r\nserver: rust\r\ncontent-type: {}\r\n\r\n{}", 
531                        status_line,
532                        contents.len(),
533                        rest_ype,
534                        contents
535                    );
536                    
537                    stream.write(response.as_bytes()).unwrap();
538                    stream.flush().unwrap();
539                },
540                1 => {
541                    let mut contents:String = String::from("");
542                    println!("fhtml:{:?}",fhtml);
543                    if fhtml == "" {
544                        // let mut file = File::open(filename).unwrap();
545                        // file.read_to_string(&mut contents).unwrap();
546                        // contents = fs::read_to_string(filename).unwrap();
547                        contents = format!("图片");
548                    }else{
549                        contents = fhtml.to_string();
550                    }
551                    //let contents = fs::read(filename).unwrap();
552                    let response: String = format!(
553                        "{:?}\r\nContent-Length: {:?}\r\nserver: rust\r\ncontent-type: {:?}\r\n\r\n{:?}", 
554                        status_line,
555                        contents.len(),
556                        rest_ype,
557                        contents
558                    );
559                    stream.write(response.as_bytes()).unwrap();
560                    stream.flush().unwrap();
561                },
562                2 => {
563                    let contents = fs::read(filename).unwrap();
564                    // let mut file = File::open(filename).unwrap();
565                    // let mut contents = String::new();
566                    // file.read_to_string(&mut contents).unwrap();
567                    let response: String = format!(
568                        "{:?}\r\nContent-Length: {:?}\r\nserver: rust\r\ncontent-type: {:?}\r\n\r\n{:?}", 
569                        status_line,
570                        contents.len(),
571                        rest_ype,
572                        contents
573                    );
574                    //let responses = concat_bytes!(status_line.as_bytes(),b"\r\nContent-Length: ",contents.len().as_bytes(),b"\r\nserver: rust\r\ncontent-type:",rest_ype.as_bytes(),b"\r\n\r\n",contents);
575                    stream.write(response.as_bytes()).unwrap();
576                    stream.flush().unwrap();
577                },
578                _ => println!("over"),
579    
580                
581            }
582    
583            // let conrent = fs::read(filename).unwrap();
584    
585            //println!("conrent:{:?}",conrent);
586            
587        }
588        
589    
590    }
591
592
593    // 待开发 websocker服务器
594    fn websockserver(&'a self, mut stream:TcpStream, buffer: [u8;BUF_NUM], mut a: bool) -> (TcpStream,bool) {
595
596        let mut n: i32 = 0;
597        let ns: i32 = 10000;
598        let close = b"[>close<]"; //tcp 关闭连接口令
599        let tcpbeat = b"tcpbeat"; //tcp 心跳请求
600
601        let response = "HTTP/1.1 200 OK";
602        let notfound = "HTTP/1.1 404 NOT FOUND";
603    
604        let httptop = "POST";
605        let httpcode:&str = " HTTP/1.1\r\n";
606        let webserver = "Upgrade: websocket";
607        let mut status_line: &str = "";
608        let mut filename: &str = "";
609        let uri = "/";
610    
611        let kongge = " ";
612
613        let tcptextclose: &[u8] = &buffer[..close.len()];
614        let tcptextbeat: &[u8] = &buffer[..tcpbeat.len()];
615        let getuserip = stream.peer_addr().unwrap();
616
617        if tcptextclose == close {//检测是否是关闭口令
618            let response:String = format!("你好!你正在向服务端请求关闭连接。");
619            stream.write(response.as_bytes()).unwrap();
620            stream.flush().unwrap();
621            println!("关闭连接");
622            stream.shutdown(Shutdown::Both).expect("shutdown call failed");//关闭客户连接
623            n = ns;
624        }else if tcptextbeat ==  tcpbeat {
625            n = 0;
626            let response:String = format!("与服务器心跳连接成功!");
627            stream.write(response.as_bytes()).unwrap();
628        }else{
629            n=0;
630            let response: &[u8] = "无广播消息!".as_bytes();
631
632            
633        }
634    
635        if filename == "" {
636            let ais:String =  httptop.to_string() + &kongge.to_string() + &uri.to_string() + &httpcode.to_string();
637            let ai:&Vec<u8> = &ais.into_bytes();
638            (status_line,filename) = if buffer.starts_with(ai) {
639                (response, "h/main.html")
640            }else{
641                (notfound, "h/404.html")
642            }
643        }
644        
645        stream.write(response.as_bytes()).unwrap();
646    
647        stream.flush().unwrap();
648    
649
650        if n >= ns{
651            println!("退出循环");
652            stream.shutdown(Shutdown::Both).expect("shutdown call failed");//关闭客户连接
653            println!("\n超出心跳时间,{}次问询后无响应。----{}-----\n\n\n",n,getuserip);
654            a = true;
655        }
656
657        n += 1;
658
659        (stream,a)
660    }
661
662    /// 验证配置文件是否配置是否正确配置
663    /// 
664    fn initconfig(&'a self) -> bool {
665        if self.top_templ == "".to_string()
666        || self.dow_templ == "".to_string() {
667            println!("未设置模板关键字!");
668            return false;
669        }
670        if self.overtext == "" {
671            println!("未设置关闭关键字,默认关键字\"over\"! ");
672            return false;
673        }
674        if self.http_app_top.len() == 1 
675        || self.http_app_top[0].0 == "" {
676            println!("http_route 中没有反射数据! ");
677            return false;
678        }
679        true
680    }
681
682
683
684
685
686}
687
688///
689/// **** tokio多线程网站服务器 开始 *****
690/// 
691/// 
692
693/// ipaddre ip和端口的映射
694/// 
695/// http_app_top
696/// ├ 路径路由方法
697/// ├ 上传方式方式
698/// ├ 传输信息
699/// ├ 成员数量
700/// 
701/// ipaddnum
702/// ip地址的个数 http_setbpost 增加
703/// 
704/// pool_num
705/// 线程个数
706/// 
707/// top_templ
708/// dow_templ 变量头尾
709/// 
710/// overtext 结束关键字
711/// 
712#[derive(Debug, Clone)] 
713pub struct  TCmlServer {
714    ipaddre: [&'static str;IPADDARRNUM],
715    http_app_top: Vec<( &'static str, Func,  ([&'static str;30], [&'static str;4])) >,
716    ipaddnum:usize,//ip个数
717    top_templ:String,
718    dow_templ:String,
719    overtext:String,
720}
721
722
723impl <'a >TCmlServer {
724    /// 声明一个 web、websocket以及tcp服务。
725    /// 
726    /// # Examples
727    /// 
728    /// 绑定一个ip和端口"0.0.0.0:8000" 到当前服务,并且开启10个工作线程。
729    /// 
730    /// let mut cml = TCmlServer::new("0.0.0.0:8000").await;
731    /// 
732    /// 设置ip以及post
733    /// pnum 设置多个线程数
734    pub async fn new(ipadd:&'static str) -> TCmlServer {
735        let mut ipaddarr:[&str;IPADDARRNUM] = ["";IPADDARRNUM];
736        ipaddarr[0] = ipadd;
737       
738        TCmlServer{
739            ipaddre: ipaddarr,
740            http_app_top: vec![( "", ne,  (["";30], ["";4]))],
741            ipaddnum:   1,
742            top_templ:  "".to_string(),
743            dow_templ:  "".to_string(),
744            overtext:   "over".to_string(),
745        }
746    }
747
748    /// 添加备用ip和端口
749    /// 
750    /// # Examples
751    /// 
752    /// cml.http_setbpost("0.0.0.0:8001");
753    /// 设置备用的ip和post。
754    /// 
755    async fn http_setbpost(&'a mut self,inpost:&'static str){
756        let mut post = self.ipaddre.clone();
757        'tc: for inr in 0..post.len() {
758            if post[inr] == "" {
759                post[inr] = &inpost;
760                break 'tc;
761            }
762        }
763        self.ipaddnum += 1;
764        self.ipaddre = post;
765    }
766
767    /// templ 中的string是为了在模板中识别变量替换文本用的关键字
768    /// 
769    /// 例如 模板中的变量为 {$pname}
770    /// 
771    /// 将用 templ("{$".to_string(),"}".to_string()).await; 来处理这变量个分割数据方法
772    /// 
773    pub async fn templ(&'a mut self , top_template: String, down_template:String) {
774        self.top_templ = top_template;
775        self.dow_templ = down_template;
776    }
777
778    ///优雅的结束服务
779    /// 
780    /// # Examples
781    /// cml.over_text("over").await;
782    /// 
783    /// shell $ over 
784    /// 当shell中输入 over 后程序结束进程并关闭
785    /// 结束进程关闭程序。
786    /// 
787    /// 
788    pub fn over_text(&'a mut self,text:&str){
789        self.overtext = format!("{}\r\n",text);
790    }
791
792    /// http server 设置目录和内容地址
793    /// 
794    /// # Examples
795    /// 
796    /// TCmlServer.http_route( "/sleep?user&name", sleep,"get|post").await;
797    /// 
798    /// 设置目录地址。
799    /// 
800    /// 主要是三个问题 一个是方法 二是地址
801    /// 
802    pub async fn http_route (
803        &'a mut self, 
804        pathdata: &'static str, 
805        html_fun: Func,
806        port: &'static str,
807    ) {
808        // let a = Html_fu(htmlfunc,"url路径");
809        let pathsplit: Vec<&str> = pathdata.split("?").collect();
810        let path = pathsplit[0];
811        let webdata = match pathsplit.len() {
812            1 => "",
813            _=>pathsplit[1],
814        };
815
816        let mut app_top = self.http_app_top.clone();
817        let webdata_split :Vec<&str> = webdata.split("&").collect();
818        let web_port:Vec<&str> = port.split("|").collect();
819        let mut webport = ["";4];
820
821        webport = match web_port.len() {
822            4 => {
823                [web_port[0],web_port[1],web_port[2],web_port[3]]
824            },
825            3 => {
826                [web_port[0],web_port[1],web_port[2],""]
827            },
828            2 => {
829                [web_port[0],web_port[1],"",""]
830            },
831            1 => {
832                if web_port[0] =="" {
833                    ["get","","",""]
834                }else{
835                    [web_port[0],"","",""]
836                }
837            },
838            _ => {
839                ["get","","",""]
840            }
841        };
842
843        let mut webdata_z = ["";30];
844        
845        for (ind,val) in webdata_split.iter().enumerate() {
846            webdata_z[ind] = val;//webdata_split[ind];
847        }
848
849        'tzcp: for int in 0..app_top.len() {
850            if app_top[int].0 == "" {
851                app_top[int] = (path,html_fun,(webdata_z,webport));
852                let pat = path.clone();
853                if pat != "/" {
854                    let pat = pat.to_string() + "/";
855                    //app_top[int+1] = (Box::leak(pat.into_boxed_str()),html_fun,(webdata_z,webport));
856                    app_top.push((Box::leak(pat.into_boxed_str()),html_fun,(webdata_z,webport)));
857                }
858                
859                break 'tzcp;
860            }else{
861                    let pat = path.to_string();
862                    app_top.push((Box::leak(pat.into_boxed_str()),html_fun,(webdata_z,webport)));
863                }
864        }
865        
866        self.http_app_top = app_top;
867    }
868
869
870
871
872    /// 执行程序
873    /// 
874    ///  # Examples
875    /// 
876    /// cml.biud().await;
877    /// 执行监听和执行。
878    /// 
879    pub async fn biud(&'a self) {
880        if self.top_templ == "".to_string()
881        || self.dow_templ == "".to_string() {
882            println!("未设置模板关键字!");
883            return;
884        }
885        if self.overtext == "" {
886            println!("未设置关闭关键字,默认关键字\"over\"! ");
887            return;
888        }
889        if self.http_app_top.len() == 1 
890        || self.http_app_top[0].0 == "" {
891            println!("http_route 中没有反射数据! ");
892            return;
893        }
894        match self.initconfig() {
895            true => {
896
897            },
898            _ => {
899                println!("请查找相关配置!");
900                return ;
901            }
902        }
903
904        let ipaddres = self.ipaddre.clone();
905        
906        let mut listener = TokioTcpListener::bind(&ipaddres[0]).await.map_err( stringify ).unwrap();
907        
908        cxdy(&ipaddres[0]);
909
910        loop {
911            let (mut socket, address) = listener.accept().await.unwrap();
912
913            //struct 上面标记 #[derive(Clone)] 才能够使用clone功能
914            //这里为什么需要clone呢?因为我们需要在下面把 self 传递到一个异步的代码块中。这意味着 handle_client 和 &mut self 的生命周期是相同的。但是这不不符预期,因为我们想在多个线程生运行 handle_client 以更好的性能。或者产生多个 handle_client 并将它们全部并行运行。如果对 self中的值 的引用存在于 handle_client 2 中,这就不可能了。所以需要将self拷贝出来。
915            let this = self.clone();
916            tokio::spawn(async move {
917                // socket.write(format!("{:?}\r\nContent-Length:{:?}\r\n\r\n{:?}","HTTP/1.1 200 OK","rust server".len(),"rust server").as_bytes()).await.unwrap();
918                this.handle_client(socket).await;
919            }).await;
920        }
921
922        
923    }  
924
925    //消息处理 War thunder
926    async fn handle_client(&'a self,mut stream: TokioTcpStream){
927
928        let mut n: i32 = 0;
929        let ns: i32 = 10000;
930        let tcpclose = b"tcpclose"; //tcp 关闭连接口令
931        let tcpbeat = b"tcpbeat"; //tcp 心跳请求
932
933        let mut buffer:[u8; BUF_NUM] = [0; BUF_NUM];
934
935        let mut dl: Textlist = Textlist::new();
936        
937        'a:loop {
938            stream.read(&mut buffer[..]).await.unwrap();
939            let mut buf_n: u8 = 0;
940            buf_n = self.isservertype(buffer,buf_n);
941            println!("{}",String::from_utf8_lossy(&buffer[..]));
942            println!("type :{}",buf_n);
943            
944            match buf_n {
945                0 => {
946                    let httptext = String::from_utf8_lossy(&buffer[..]);
947                    println!("tcp msg:{}",httptext);
948                
949                    let tcptextclose: &[u8] = &buffer[..tcpclose.len()];
950                    let tcptextbeat: &[u8] = &buffer[..tcpbeat.len()];
951                    let getuserip = stream.peer_addr().unwrap();
952                    
953                    if tcptextclose == tcpclose {//检测是否是关闭口令
954                        let response:String = format!("你好!你正在向服务端请求关闭。");
955                        stream.write(response.as_bytes()).await.unwrap();
956                        stream.flush().await.unwrap();
957                        println!("关闭连接");
958                        stream.shutdown().await.expect("shutdown call failed");//关闭客户连接
959                        n = ns;
960                    }else if tcptextbeat ==  tcpbeat{
961                        n = 0;
962                        let response:String = format!("与服务器心跳连接成功!");
963                        stream.write(response.as_bytes()).await.unwrap();
964                    } else {
965                        n=0;
966                        let response: &[u8] = "无广播消息!".as_bytes();
967                        
968                        if !dl.is_empty(){
969                            let response = dl.theone(0);
970                            // println!("qmsg:{:?}",response);
971                        }else{
972                            // println!("qmsg is null!");
973                        }
974                        
975                        dl.push(buffer);
976                        
977                        dl.printdl();
978                        stream.write(response).await.unwrap();
979                    }
980                    
981    if !dl.is_empty(){
982        let dlp = dl.theone(0);
983        // for i in *dlp {
984        //     if i != 0{
985        //         println!("buff.0: {}",i);
986        //     }
987        // }
988    }
989    
990                    if n >= ns{
991                        println!("退出循环");
992                        stream.shutdown().await.expect("shutdown call failed");//关闭客户连接
993                        println!("\n超出心跳时间,{}次问询后无响应。----{}-----\n\n\n",n,getuserip);
994                        break 'a;
995                    }
996                    
997                    n += 1;
998                    println!("\n----{}-----{}-----\n\n\n",getuserip,n);
999                },
1000                2 => {
1001                    stream = self.http_to_server(stream,buffer).await;
1002                    break 'a;
1003                },
1004                buf_n if buf_n == 3 => {
1005                    //websockserver( stream);
1006                },
1007                _ => println!("over"),
1008            }
1009
1010        }
1011        println!(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>结束 等待下一次连接!\r\n\r\n\r\n");
1012    }
1013
1014
1015    async fn http_to_server(&'a self,mut stream:TokioTcpStream,mut buffer: [u8;BUF_NUM]) -> TokioTcpStream {
1016        let response = "HTTP/1.1 200 OK";
1017        let notfound = "HTTP/1.1 404 NOT FOUND";
1018        let httpcode:&str = " HTTP/1.1\r\n";
1019        let httptop = ["GET","POST","PUT","DELETE"];
1020        let uri: Vec<( &'static str, Func,  ([&'static str;30], [&'static str;4])) > = self.http_app_top.clone();
1021        let mut status_line: &str = "";
1022        let mut filename: &str = "";
1023        let mut rest_ype: String = String::from("");
1024        let mut rest_ype_num: u8 = 0;
1025        let mut aus:String;
1026        let mut pzjg = false;
1027        let mut fhtml:String = "".to_string();
1028    
1029        'httpt: for i in httptop {
1030            let b:&[u8] = &i.to_string().into_bytes();
1031            
1032            if buffer.starts_with(b) {
1033                for s in &uri{
1034                    
1035                    if s.0 == "" {
1036                        break 'httpt;
1037                    }
1038
1039                    let topbu = if_split(&buffer, httpcode);
1040                    let aansbool = wscmlsuffix(topbu,s,i);
1041                    let favicon:String = format!("{} {}favicon.ico",i,s.0);
1042                    let afavicon:&Vec<u8> = &favicon.into_bytes();
1043                    let jpg:String = format!("{} {}1.jpg",i,s.0);
1044                    let afavjpg:&Vec<u8> = &jpg.into_bytes();
1045
1046                    // println!("文件内部:{:?}",topbuf[0]);
1047                    (status_line,filename,rest_ype,rest_ype_num,pzjg,fhtml) = 
1048                    if aansbool {
1049                        aus = wscmlurl(s);
1050
1051                        fhtml = wscmldata(self.top_templ.clone(),self.dow_templ.clone(),buffer,s);
1052
1053                        (response, &aus[..],String::from("text/html; charset=UTF-8"),0,true,fhtml)
1054                    } else if buffer.starts_with(afavicon) {
1055                        (response, "h/favicon.ico",String::from("image/x-icon"),1,true,"".to_string())
1056                    } else if buffer.starts_with(afavjpg) {
1057                        (response, "h/1.jpg",String::from("image/jpeg"),2,true,"".to_string())
1058                    } else {
1059                        (notfound, "h/404.html",String::from("text/html; charset=UTF-8"),0,false,"".to_string())
1060                    };
1061    
1062                    if pzjg == true {
1063                        break 'httpt;
1064                    }
1065                }
1066            }
1067        }
1068    
1069        println!("这url地址:{:?} match:{:?}",filename,rest_ype_num);
1070    
1071        if filename != "" {
1072            match rest_ype_num {
1073                0 => {
1074                    let mut contents:String = String::new();
1075                    if fhtml == "" {
1076                        let mut c = tokiofs::File::open(filename).await.unwrap();
1077                        
1078                        c.read_to_string(&mut contents).await.unwrap();
1079                    }else{
1080                        contents = fhtml.to_string();
1081                    }
1082                    //let contents: String =  fs::read_to_string(filename).unwrap();
1083
1084                    let response: String = format!(
1085                        "{}\r\nContent-Length: {}\r\nserver: rust\r\ncontent-type: {}\r\n\r\n{}", 
1086                        status_line,
1087                        contents.len(),
1088                        rest_ype,
1089                        contents
1090                    );
1091                    
1092                    stream.write(response.as_bytes()).await.unwrap();
1093                    stream.flush().await.unwrap();
1094                },
1095                1 => {
1096                    let mut contents:String = String::from("");
1097                    println!("fhtml:{:?}",fhtml);
1098                    if fhtml == "" {
1099                        // let mut file = File::open(filename).unwrap();
1100                        // file.read_to_string(&mut contents).unwrap();
1101                        // contents = fs::read_to_string(filename).unwrap();
1102                        contents = format!("图片");
1103                    }else{
1104                        contents = fhtml.to_string();
1105                    }
1106                    //let contents = fs::read(filename).unwrap();
1107                    let response: String = format!(
1108                        "{:?}\r\nContent-Length: {:?}\r\nserver: rust\r\ncontent-type: {:?}\r\n\r\n{:?}", 
1109                        status_line,
1110                        contents.len(),
1111                        rest_ype,
1112                        contents
1113                    );
1114                    stream.write(response.as_bytes()).await.unwrap();
1115                    stream.flush().await.unwrap();
1116                },
1117                2 => {
1118                    let contents = tokiofs::read(filename).await.unwrap();
1119                    // let mut file = File::open(filename).unwrap();
1120                    // let mut contents = String::new();
1121                    // file.read_to_string(&mut contents).unwrap();
1122                    let response: String = format!(
1123                        "{:?}\r\nContent-Length: {:?}\r\nserver: rust\r\ncontent-type: {:?}\r\n\r\n{:?}", 
1124                        status_line,
1125                        contents.len(),
1126                        rest_ype,
1127                        contents
1128                    );
1129                    //let responses = concat_bytes!(status_line.as_bytes(),b"\r\nContent-Length: ",contents.len().as_bytes(),b"\r\nserver: rust\r\ncontent-type:",rest_ype.as_bytes(),b"\r\n\r\n",contents);
1130                    stream.write(response.as_bytes()).await.unwrap();
1131                    stream.flush().await.unwrap();
1132                },
1133                _ => println!("over"),
1134    
1135                
1136            }
1137    
1138            // let conrent = fs::read(filename).unwrap();
1139    
1140            //println!("conrent:{:?}",conrent);
1141    
1142            
1143        }
1144    
1145        return stream;
1146    
1147    }
1148
1149
1150    /// 判断接受tcp信息的类型
1151    /// 0 tcp
1152    /// 
1153    /// 
1154    /// 1 只是标记http请求来源为http/1.1
1155    /// 2 http
1156    /// 3 websocket
1157    /// 
1158    /// 
1159    fn isservertype(&'a self,buffer: [u8;BUF_NUM],mut n: u8) -> u8 {
1160        let tcjc = [0;BUF_NUM];
1161        if tcjc != buffer {
1162            for i in 0..BUF_NUM {
1163                let lll: [u8;HTVNUM] = [0;HTVNUM];
1164                if i + HTVNUM < BUF_NUM{
1165                    let splits = &buffer[i..(i+HTVNUM)];
1166                    if  &splits == HTV
1167                    &&  &splits != &lll{ 
1168                        //println!("PBNUM:{:?},pbunm:{:?}",String::from_utf8_lossy(&splits[..]),&splits);
1169                        if n == 0 {
1170                            n = 1;
1171                        }
1172                    }
1173                }
1174    
1175                let lll: [u8;HTTPPDNUM] = [0;HTTPPDNUM];
1176                if  i + HTTPPDNUM <= BUF_NUM{
1177                    let splits = &buffer[i..(i+HTTPPDNUM)];
1178                    if  &splits == HTTPPD
1179                    &&  &splits != &lll
1180                    &&  (n == 0 || n == 1){
1181                        n = 2;
1182                    }
1183                }
1184    
1185                let lll: [u8;WSNUM] = [0;WSNUM];
1186                if  i + WSNUM <= BUF_NUM{
1187                    let splits = &buffer[i..(i+WSNUM)];
1188                    if  &splits == WS
1189                    &&  &splits != &lll
1190                    &&  (n == 0 || n == 1){
1191                        n = 3;
1192                    }
1193                }
1194                
1195            }
1196        }
1197    
1198        return n;
1199    }
1200
1201    /// 验证配置文件是否配置是否正确配置
1202    fn initconfig(&'a self) -> bool {
1203        if self.top_templ == "".to_string()
1204        || self.dow_templ == "".to_string() {
1205            println!("未设置模板关键字!");
1206            return false;
1207        }
1208        if self.overtext == "" {
1209            println!("未设置关闭关键字,默认关键字\"over\"! ");
1210            return false;
1211        }
1212        if self.http_app_top.len() == 1 
1213        || self.http_app_top[0].0 == "" {
1214            println!("http_route 中没有反射数据! ");
1215            return false;
1216        }
1217        true
1218    }
1219
1220
1221}