最重要的一个类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. 第10章 深入理解Session与Cookie

    需要很多Cookie时,考虑HTTP对Cookie数量和大小的限制. 几百或更多台服务器的时候,如何解决Session在多态服务器之间共享的问题. 还有一些安全问题,如Cookie被盗,Cookie伪 ...

  2. 温故而知新(java实现)单例模式的七种写法

    第一种(懒汉,线程不安全): Java代码 public class Singleton { private static Singleton instance; private Singleton ...

  3. python web指纹获取加目录扫描加端口扫描加判断robots.txt

    前言: 总结上几次的信息收集构造出来的. 0x01: 首先今行web指纹识别,然后在进行robots是否存在.后面是目录扫描 然后到使用nmap命令扫描端口.(nmap模块在windows下使用会报停 ...

  4. php各版本编译好的扩展模块下载地址

    php各版本[,x86/64  v9/v11/v14  nts/ts]编译好的扩展模块下载地址: https://windows.php.net/downloads/pecl/releases/ ht ...

  5. 自定义inputformat和outputformat

    1. 自定义inputFormat 1.1 需求 无论hdfs还是mapreduce,对于小文件都有损效率,实践中,又难免面临处理大量小文件的场景,此时,就需要有相应解决方案 1.2 分析 小文件的优 ...

  6. localtime 的性能问题及其替代者

    在系统从redhat5升到redhat6的过程中,服务的性能差了很多.经过定位发现是程序中频繁调用localtime/localtime_r所致. 而调用localtime_r 的实现中,对时区进行了 ...

  7. .find()和.index()的区别

    今天在复习基本数据类型——字符串的时候,有一点想法,总结一下: 字符串的定义:字符串是一个有序的字符集合,用于存储和表示基本的文字信息,用‘,“,‘’‘括起来的称之为字符串. 字符串的操作有很多种,比 ...

  8. Redis搭建(三):哨兵模式

    一.sentinel介绍 Redis 2.8中提供了“哨兵”工具来实现自动化的系统监控和故障恢复功能. Redis 2.6 版也提供了哨兵工具,但此时的哨兵是1.0版,存在非常多的问题,任何情况下都不 ...

  9. JQuery实现瀑布流页面

    views.py from django.shortcuts import render,HttpResponse from app01 import models import json # Cre ...

  10. CrackMe的简单破解

    [CrackMe的简单破解] 对于以下这样的输入账号和密码的窗口,我们可以猜测该程序使用最简单的机制实现,即用strmp来比较用户输入的密码和原始密码匹配.所以为了破解该程序,可以通过bp strmp ...