最重要的一个类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. Rest之路 - 介绍篇

    What is REST ? REST 是 REpresentational State Transfer 的缩写.是一种基于HTTP协议来进行进行数据交换的web标准框架.她的思想是:视组件为资源. ...

  2. 第一章 初识MySQL(待续)

    ···········

  3. Hibenate错误汇总:java.lang.NoClassDefFoundError: org/jboss/logging/BasicLogger

    转自:https://bioubiou.iteye.com/blog/1769950 1 Hibenate异常汇总:java.lang.NoClassDefFoundError: org/jboss/ ...

  4. vue简单路由(一)

    在项目中,将vue的单页面应用程序改为了多页面应用程序,因此在某些场景下,需要频繁的切换两个页面,因此考虑使用路由,这样会减少服务器请求. 使用vue-cli(vue脚手架)快速搭建一个项目的模板(w ...

  5. https ssl

    HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版.即HTTP下加入 ...

  6. 【转发】徐汉彬:Web系统大规模并发——电商秒杀与抢购

    徐汉彬:Web系统大规模并发——电商秒杀与抢购 发表于2014-12-02 09:30| 73110次阅读| 来源CSDN| 114 条评论| 作者徐汉彬 问底徐汉彬大数据 摘要:电商的秒杀和抢购,从 ...

  7. 【更多教程关注公众号全要买】1-2 Disruptor与BlockingQueue压力测试性能对比

    JDK所提供的BlockingQueue替换成Dis

  8. 03-nginx虚拟主机配置

    不想用kill命令控制nginx也行,但是其他命令没有信号的命令丰富.重读配置文件不用重启nginx(软重启).完全可以使用stop(强制退出).quick(优雅退出).reopen(重新打开日志). ...

  9. 【codevs2822】爱在心中

    题目描述 Description “每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动.爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢Our Home.” 在爱的国度 ...

  10. 生成ico格式图标

    ico格式可参考如下链接: http://msdn.microsoft.com/en-us/library/ms997538.aspx http://en.wikipedia.org/wiki/ICO ...