最重要的一个类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 = ;
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[];//10KB的接受消息量 int dataCount = dataSocket.Receive(bytedata);//转换消息 string strReceived = DataToString.GetString(bytedata, , dataCount);//转换字节到string GetStockString = strReceived; OnStocketStringChange?.Invoke(strReceived);//事件传递参数到viewmodel string httpmethod = strReceived.Substring(, strReceived.IndexOf(" "));//获取第一个空格到起始位置之间所有的字符 int StartMethodUrl = strReceived.IndexOf(httpmethod) + httpmethod.Length + ;//获取请求内容的起始位置。也是直接写作httpmethod.length+1 int EndMethodUrl = strReceived.Substring(, strReceived.IndexOf("\r\n")).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('?')[];//分割字符串 也可以是RequestedFile.Split('?').Length>1?RequestedFile.Split('?')[0]:RequestedFile;
int TypeNameStart =RequestedFile.LastIndexOf(".") + ; int TypeNameLength = ; string Extension = "."; switch(TypeNameStart>)
{
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 + "\r\n"
+ "Server: Atasoy Simple Web Server\r\n"
+ "Content-Length: " +SendContent.Length.ToString() + "\r\n"
+ "Connection: close\r\n"
+ "Content-Type: " + SendContentType + "\r\n\r\n"); var AllDataByte = new byte[SendContent.Length + header.Length];//复制两个数组 Buffer.BlockCopy(header, , AllDataByte, , header.Length); Buffer.BlockCopy(SendContent, , AllDataByte, header.Length, SendContent.Length); Send.Send(AllDataByte);//发送 Send.Close();
}
catch
{ }
} public delegate void StocketStringChange(string sender);//委托
public event StocketStringChange OnStocketStringChange;//事件 }
}

基本的模式就是

开始监听

利用两个线程来处理信息

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

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

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

最重要的是对消息的处理

Socket 简易静态服务器 WPF MVVM模式(四)的更多相关文章

  1. Socket 简易静态服务器 WPF MVVM模式(一)

    整体代码下载 主要实现功能: Socket的简单应用 可修改IP和端口 显示来访信息 界面设计: 界面采用MVVM设计,很简陋. 前台的主要目的是 输入IP地址 输入端口 输入文件目录 开启监听和停止 ...

  2. Socket 简易静态服务器 WPF MVVM模式(三)

    ViewModels类 这个类其实就是个大杂烩,什么都可以用 这个类没有什么东西,最多的就是写一下xaml页面的逻辑控制,开启关闭监听 using System; using System.Colle ...

  3. Socket 简易静态服务器 WPF MVVM模式(二)

    command类 标准来说,command会有三种模式,委托命令 准备命令 附加命令 1.DelegateCommand 2.RelayCommand 3.AttachbehaviorCommand ...

  4. WPF MVVM模式的一些理解

    /*本文转自 http://www.cnblogs.com/sirkevin/archive/2012/11/28/2793471.html */ 使用WPF+Mvvm开发一年多,期间由于对Mvvm模 ...

  5. WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍

    WPF自学入门(十一)WPF MVVM模式Command命令   在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式 ...

  6. wpf mvvm模式下CommandParameter传递多参

    原文:wpf mvvm模式下CommandParameter传递多参 CommandParameter一般只允许设置一次,所以如果要传递多参数,就要稍微处理一下.我暂时还没找到更好的方案,下面介绍的这 ...

  7. WPF MVVM模式中,通过命令实现窗体拖动、跳转以及显隐控制

    原文:WPF MVVM模式中,通过命令实现窗体拖动.跳转以及显隐控制 在WPF中使用MVVM模式,可以让我们的程序实现界面与功能的分离,方便开发,易于维护.但是,很多初学者会在使用MVVM的过程中遇到 ...

  8. WPF MVVM模式下的无阻塞刷新探讨

    很多时候我们需要做一个工作,在一个方法体里面,读取大数据绑定到UI界面,由于长时间的读取,读取独占了线程域,导致界面一直处于假死状态.例如,当应用程序开始读取Web资源时,读取的时效是由网络链路的速度 ...

  9. WPF自学入门(十一)WPF MVVM模式Command命令

    在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式.正如上一篇文章中在开始说的,MVVM的目的是为了最大限度地降低了 ...

随机推荐

  1. kali下apche配置多网站

    设置文件地址为 :/etc/apache2/sites-available/default 添加: <VirtualHost *:80>       ServerName www.php. ...

  2. Oracle里的执行计划

    1 执行计划的查看 1 explan plan 2 dbms_xplan包 3 sqlplus中 set autot 4 10046 5 awr报告 6一些现成的脚本 7 10053 常见的就前4种 ...

  3. django-上传文件 fromdata(头像实例)

    上传文件头像的2种方法,简单实例来看下用法 用法定义,fromdata可以传输任何数据 HttpRequest.FILES 一个类似于字典的对象,包含所有的上传文件信息. FILES 中的每个键为&l ...

  4. 根文件系统的构建与分析(四)之瑞士军刀busybox生成系统基本命令

    根文件系统的构建与分析(四) 转载请注明 http://blog.csdn.net/jianchi88   Author:Lotte   邮箱:baihaowen08@126.com ls /bin, ...

  5. apache 不解析 php

    apache 不解析php 1.找到: AddType application/x-gzip .gz .tgz在其下面添加: AddType application/x-httpd-php .php ...

  6. ngnix 403 forbidden的解决办法

    1.在网站根目录下新建文件index.html.index.php. 2.主要是修改nginx的配置文件nginx.conf权限为755即可访问.

  7. 初学Python--列表(List)

    1.索引 列表中的元素类型未必统一,如: listExample=[1,2,'a','b'] 元素下标索引以0开始 firstEle=listExample[0] 不能进行越界索引,但可以倒序索引 l ...

  8. cin cout getline string

    1.C++ code, When we want to read a number whatever the type is int or double , just use cin >> ...

  9. leetcode852

    int peakIndexInMountainArray(vector<int>& A) { int Len = A.size(); ; ; i < Len - ; i++) ...

  10. C++中不可重载5个运算符

    C++中不可重载的5个运算符 C++中的大部分运算符都是可以重载的,只有以下5个运算符不可以重载,他们是: 1  .(点运算符)通常用于去对象的成员,但是->(箭头运算符),是可以重载的   2 ...