zoukankan      html  css  js  c++  java
  • Socket 简易静态服务器 WPF MVVM模式(四)

    最重要的一个类Socket类

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace 简易静态服务器.Code
    {
        public class Server
        {
            public string GetStockString { get; private set; }
            private bool runing = false;
            private Socket ServerSocket;
            private int timeout = 10;
            private string fileurl;
            private Encoding DataToString = Encoding.UTF8;
            private string RequestedFile = string.Empty;
            public bool Start(IPAddress Ip,int prot,int Count,string fileurl)
            {
                if (runing) return false;
    
                try
                {
                    ServerSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);//监听类型
                    ServerSocket.Bind(new IPEndPoint(Ip,prot));
                    ServerSocket.Listen(Count);//监听实例的数量
                    ServerSocket.ReceiveTimeout = timeout;//超时
                    ServerSocket.SendTimeout = timeout;//超时
                    runing = true;
                    this.fileurl = fileurl;
                }
                catch { return false; }
    
                Thread requestListenerThread = new Thread(() =>{ //多线程进行处理
    
                    while (runing) //设置一直开启
                    {
                        Socket clientSocket;
                        try
                        {
                            clientSocket = ServerSocket.Accept();//等待接收数据 是方法内部的线程堵塞
    
                            var Handler  = new Thread(() => {
                                clientSocket.ReceiveTimeout = timeout;
                                clientSocket.SendTimeout = timeout;
                                try
                                {
                                    GetData(clientSocket);
                                }
                                catch
                                {
                                    try { clientSocket.Close(); } catch { }
                                }
    
                            });
                            Handler.Start();
                           
                        }
                        catch
                        {
    
                        }
                    }
                });
                requestListenerThread.Start();
                return true;
            }
            public void Stop()
            {
                if(runing)
                {
                    runing = false;
                    try
                    {
                        ServerSocket.Close();
                    }
                    catch { }
                    ServerSocket.Dispose();
                    ServerSocket = null;
                }
            }
            private void GetData(Socket dataSocket)
            {
                var bytedata = new byte[10240];//10KB的接受消息量
    
                int dataCount = dataSocket.Receive(bytedata);//转换消息
    
                string strReceived = DataToString.GetString(bytedata, 0, dataCount);//转换字节到string
    
                GetStockString = strReceived;
    
                OnStocketStringChange?.Invoke(strReceived);//事件传递参数到viewmodel
              
                string httpmethod = strReceived.Substring(0, strReceived.IndexOf(" "));//获取第一个空格到起始位置之间所有的字符
    
                int StartMethodUrl = strReceived.IndexOf(httpmethod) + httpmethod.Length + 1;//获取请求内容的起始位置。也是直接写作httpmethod.length+1
    
                int EndMethodUrl = strReceived.Substring(0, strReceived.IndexOf("
    ")).IndexOf("HTTP") - StartMethodUrl; //strReceived.LastIndexOf("HTTP") - StartMethodUrl - 1;
    
                
                string MethodUrl = strReceived.Substring(StartMethodUrl, EndMethodUrl);//获取请求内容
    
                switch(httpmethod)
                {
                    case "GET":
                    case "POST":
                        RequestedFile = MethodUrl;
                        break;
                    default:
                        dataSocket.Close();//此处也可以是  NotImplemented(dataSocket);
                        return;
                }
    
                RequestedFile = RequestedFile.Replace("/", "\").Replace("\..", "");//替换斜杠
                RequestedFile = RequestedFile.Split('?')[0];//分割字符串 也可以是RequestedFile.Split('?').Length>1?RequestedFile.Split('?')[0]:RequestedFile;
                int TypeNameStart =RequestedFile.LastIndexOf(".") + 1;
    
                int TypeNameLength = 0;
    
                string Extension = ".";
    
    
               switch(TypeNameStart>0)
                {
                    case true:
                        TypeNameLength = RequestedFile.Length - TypeNameStart;
                        Extension += RequestedFile.Substring(TypeNameStart, TypeNameLength).Replace(" ","");//获取请求格式的字符串
                                         
                        switch (MimeType.Type.ContainsKey(Extension))//判断是否存在这个类型
                        {
                            case true:
                                switch(File.Exists(fileurl+RequestedFile))
                                {
                                    case true:
                                        SendOKResponse(dataSocket,File.ReadAllBytes(fileurl + RequestedFile), MimeType.Type[Extension]);                                  
                                        break;
                                    case false:
                                        NotFound(dataSocket);
                                        break;
                                }
                                break;
                            case false:
                                //不存在的话 那是否直接存在这个文件?
                                if (File.Exists(fileurl + RequestedFile))//存在输出
                                    SendOKResponse(dataSocket, File.ReadAllBytes(fileurl + RequestedFile), "text/html");
                                else//不存在 501
                                    NotImplemented(dataSocket);
                                break;
                        }
                        break;
                    case false:                   
                            SendOKResponse(dataSocket, File.ReadAllBytes(fileurl + "\Index.html"), "text/html");  //直接输出index页面                
                        break;
                }
    
            }
            private void NotFound(Socket clientSocket)
            {
                SendResponse(clientSocket, "<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body><h2>Atasoy Simple Web Server</h2><div>404 - Not Found</div></body></html>", "404 Not Found", "text/html");
            }
            private void NotImplemented(Socket clientSocket)
            {
                SendResponse(clientSocket, "<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body><h2>Atasoy Simple Web Server</h2><div>501 - Method Not Implemented</div></body></html>", "501 Not Implemented", "text/html");
            }
            private void SendResponse(Socket clientSocket, string strContent, string responseCode, string contentType)
            {
                byte[] bContent = DataToString.GetBytes(strContent);
                SendResponse(clientSocket, bContent, responseCode, contentType);
            }
            private void SendOKResponse(Socket Send, byte[] SendContent, string SendContentType) =>SendResponse(Send,SendContent,简易静态服务器.Models.SendContentType.GetSendString(Models.SendType.Send200OK),SendContentType);
            private void SendResponse(Socket Send, byte[] SendContent, string SendCode, string SendContentType)
            {
                try
                {
                    //处理头部
                    var header=DataToString.GetBytes("HTTP/1.1 " + SendCode + "
    "
                                      + "Server: Atasoy Simple Web Server
    "
                                      + "Content-Length: " +SendContent.Length.ToString() + "
    "
                                      + "Connection: close
    "
                                      + "Content-Type: " + SendContentType + "
    
    ");
    
                    var AllDataByte = new byte[SendContent.Length + header.Length];//复制两个数组
    
                    Buffer.BlockCopy(header, 0, AllDataByte, 0, header.Length);
    
                    Buffer.BlockCopy(SendContent, 0, AllDataByte, header.Length, SendContent.Length);
    
                   
    
                    Send.Send(AllDataByte);//发送
                  
                    Send.Close();
                }
                catch
                {
    
                }
            }
    
            public  delegate void StocketStringChange(string sender);//委托
            public event StocketStringChange OnStocketStringChange;//事件
            
    
        }
    }

    基本的模式就是

    开始监听

    利用两个线程来处理信息

    因为socket的accept自带线程堵塞,不会造成线程的大量拥堵。

    此外还可以异步进行消息接受,发送

    对于socket的基本使用差不多如此。

    最重要的是对消息的处理

  • 相关阅读:
    IDEA快捷键:查询快捷键
    IDEA快捷键:自动代码(get、set、构造方法、try...catch、if....else、重写方法、实现方法、大小写转换、格式化、方法参数提示、方法的声明)
    查找(顺序查找、折半查找、分块查找)
    Springboot:整合Mybatis
    required a bean of type 'com.zhb.dao.StudentDao' that could not be found.
    Springboot:整合Druid
    Springboot:整合JDBC
    springboot、Thymeleaf、国际化的简单使用
    Exception evaluating SpringEL expression
    java8:四大核心函数式接口(消费型、供给型、函数型、断言型)
  • 原文地址:https://www.cnblogs.com/T-ARF/p/9933912.html
Copyright © 2011-2022 走看看