标签:ret mod .exe multi 用途 rtc fromfile dal 场景
ASP.net
第一天
C# IIS(Internet Information Service)
互联网信息服务
Java(Tomcat)
Php(Apache)
请求处理:
什么是HTTP协议?
一个基于应用层的通信规范。
浏览器和服务器的底层通信——Socket
浏览器就是一个Socket客户端
浏览器的本质作用
1.将用户输入的URL封装为一个请求报文,
2.建立与服务器端的连接,
3.将封装好的请求报文通过socket发送到服务器端,
server.write(JSON.stringify(send));
4.接收到服务端返回的响应报文,
5.解析响应报文JSON.parse,
6.渲染内容到页面当中 console.log(msg)。
如果页面中含有图片,那么浏览器渲染从服务器返回的代码时(Html),会遇到<img>标签,那么浏览器会重新发送请求,从浏览器下载该图片。
TCP
打电话:
转换成模拟信号 再转回来
网络传输:
底层是tcp,上面是http 浏览器与服务器之间用http通信,交换机什么的用到tcp 再最后转回来
静态网站 HTML+CSS+JS 前端
动态网站 C# 服务端
.ashx
如果浏览器向服务器请求的静态资源(.html,.css,.js)
那么IIS服务器直接找到这些资源返回,因为浏览器认识,如果请求是动态资源IIS处理不了,
他一看是ashx,处理不了,只能交给.netFrameWork来处理
(是通过aspnet_isapi.dll交给.NetFrameWork来处理)
最后.NetFrameWork交给IIS,IIS再返回给浏览器
托管代码与非托管代码
托管代码调用.Net Framework来执行,非托管代码调用的是Windows系统库和MFC库
aspnet_isapi.dll无法反编译,因为它是非托管代码。
扩展程序注册在命令: aspnet_regiis –i
教程中是怎么创建的。
新建——空项目——web应用程序(空) 右键添加新建项HTML 右键添加ashx
新建一个UserList.html再新建一个UserInfoList.ashx:
aspx
webForm
上面写html,下面可以写C#
微软希望网页开发能像Winform开发一样简单。
请求报文:
响应报文:
HTTP协议内容是:
上图画的不是特别准确(懒得改了)
HTTP请求:
请求行+请求头+请求体
HTTP响应:
一个简单的表单示例
HttpRequestDemo.html
Accept.ashx
get请求
1.如果是post方式进行请求,那么表单中的数据会放在请求报文体中,发送到服务器端,如果以get方式进行请求,那么表单中的数据会放在URL地址栏中发送到服务端.(注意,表单元素必须有name属性)
只能将表单元素的value值提交到服务端(span,div等不熟悉表单元素,所以无法提交),并且表单元素必须要加name属性
http协议的无状态特性,第二次请求不会拿到第一次请求的结果。
静态变量,一直存在内存中,把服务终止了才会取消。
public static int count = 0;
自增
int.parse()与convert.toint32()
int.parse(null) 抛出异常
convert.toint32(null) = 0
连接数据库读取表格
UserInfoList.html
UserInfoList.ashx
第二天
复习:
1.如果是post方式进行请求,那么表单中的数据会放在请求报文体中,发送到数据端,如果以get方式进行请求,那么表单中的数据会放在url地址栏中发送到服务端。(注意,表单元素必须有name属性)
2.在服务端接收方式不一样,如果post请求用request.Form,get请求用request.QueryString.
3.Post请求比Get请求安全,以后像注册,登录等表单都要用post提交
4.Post请求发送的数据要比get请求大。
注意:只能将表单元素的value值提交到服务端(span,div等不熟悉表单元素,所以无法提交),并且表单元素必须要加name属性。
继续完成了第一天任务未完成的 增删改查 其余部分。
(这里省略)
请求处理模型:
Kernal:操作系统内核
服务器:
操作系统:
Windows Server 2008
内核模式:
操作系统操作在内核模式下
用户模式:
应用软件操作在用户模式下。
KernalModeDriver:
http.sys
请求先到达服务器操作系统的内核模式。
交给http.sys---->对浏览器发送过来的数据做个基本的处理,
检查端口号等。将处理的结果转交给IIS
IIS是一个软件,工作在用户模式下。
对发送过来的请求进行判断,如果是静态资源(.html,.js,.css等)
直接找到这些资源后返回给浏览器。如果是动态资源,处理不了
交给aspnet_isapi.dll
工作进程.w3wp.exe
非托管模式:aspnet_isapi.dll ,加载.net framework
托管模式:.net framework
Web网站与Web应用程序的区别
(“项目”与”网站”)
“项目”中是先编译生成,如果有一个ashx有问题就不能打开了
而”网站”是可以单独访问编译
网站是请求编译,每个ashx单独生成一个DLL
context.Response.Write(System.Reflection.Assembly.GetExecutingAssembly().Location);
所以,网站一般都用WebApplication项目
域名与DNS(域名解析)
将域名转换成IP地址 ping www.baidu.com
一般处理程序手写三层(增删改查小项目)
第一节课:三层列表展示
再写一遍SqlHelper:
SqlHelper.cs
UserInfoDal.cs
最后运行
总结一下这个分层的项目:
第一步、首先建立这个解决方案,生成一些项目
BLL层 BusinessLogicLayer 业务逻辑层
DAL层 DataAccessLayer数据访问层
Model层 数据层
WebApp 是空白的Asp.net web应用程序
Common公用的小工具库(没用到)
第二步、在WebApp中配置web.config
第三步、写Model层(数据转对象)
UserInfo.cs:
第四步、写数据访问层DAL
中的SqlHelper.cs
写DAL业务逻辑层中的UserInfoDal.cs
第五步、写业务逻辑层BLL
第六步、在web项目中
UserInfoList.html:
UserInfoList.ashx:
第二节课:数据层构建完成(完善数据层)
UserInfoDal.cs
第三节课:三层详细展示(完善业务层)
添加 ShowDetail.html和ShowDetail.ashx
ShowDetail.html
ShowDetail.ashx:
工厂模式
//问题:业务层与数据层紧耦合
如果我写了一个CZBK.TestProject.AccessDAL类库,
那么在BLL层也要对应改好多东西
怎么解决呢,需要写一个数据层的访问接口:
添加Model引用
在DAL中引用IDAL接口
在UserInfoDal.cs中实现这些接口
改变业务层
业务层添加引用
重写
新建工厂:
添加引用:
写代码:
这时候原先的业务层也需要对应有改变
添加引用
写代码:(此时业务层和数据层完全解耦了)
*抽象工厂
修改config文件 而不是在vs里写class重新生成
总结: 工厂类=>生产对象
返回一个接口,因为
不管是SQLSERVERDal还是AccessDal 都实现这个接口
第三天
上传图片 Enctype
<!—enctype = “multipart/form-data”:如果上传文件时必须添加该属性,将文件内容作为请求报文体一部分à
enctype的默认取值是 application/x-www-form-urlencoded
表单里如果有文件上传域必须要加enctype。
FileUpload.html
FileUpload.ashx
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/html";
HttpPostedFile file = context.Request.Files["fileUp"];//接收文件数据
if (file == null)
{
context.Response.Write("请选择文件");
}
else
{
//判断上传的文件的类型
string fileName = Path.GetFileName(file.FileName);//获取文件名与扩展名
string fileExt = Path.GetExtension(fileName);//获取扩展名
if (fileExt == ".jpg"||fileExt == ".gif")//获取扩展名
{
file.SaveAs(context.Request.MapPath("/ImagePath/"+fileName));//保存文件
context.Response.Write("<html><head></head><body><img src=‘/ImagePath/"+ fileName +"‘></body></html>");
}
else
{
context.Response.Write("文件类型错误");
}
}
}
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/html";
HttpPostedFile file = context.Request.Files["fileUp"];//接收文件数据
if (file == null)
{
context.Response.Write("请选择文件");
}
else
{
//判断上传的文件的类型
string fileName = Path.GetFileName(file.FileName);//获取文件名与扩展名
string fileExt = Path.GetExtension(fileName);//获取扩展名
if (fileExt == ".jpg"||fileExt == ".gif")//获取扩展名
{
string dir = "/ImagePath/" + DateTime.Now.Year + "/" + DateTime.Now.Month + "/"
+ DateTime.Now.Day + "/";
//创建文件夹
Directory.CreateDirectory(Path.GetDirectoryName(context.Request.MapPath(dir)));
string newfileName = Guid.NewGuid().ToString();
string fullDir = dir + newfileName + fileExt;//构建完整的文件路径
file.SaveAs(context.Request.MapPath(fullDir));
//file.SaveAs(context.Request.MapPath("/ImagePath/"+fileName));//保存文件
context.Response.Write("<html><head></head><body><img src=‘"+ fullDir +"‘></body></html>");
//最后再将上传成功的图片路径存储到数据库,
}
else
{
context.Response.Write("文件类型错误");
}
}
}
GDI绘图
压缩图片
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string filePath = context.Request.MapPath("/ImagePath/OctoCat.jpg");
using (Bitmap map = new Bitmap(40, 40))
{
using (Graphics g = Graphics.FromImage(map))
{
using (Image image = Image.FromFile(filePath))
{
g.DrawImage(image,new Rectangle(0,0,map.Width,map.Height));
string fileName = Guid.NewGuid().ToString();
map.Save(context.Request.MapPath("/ImagePath/" + fileName + ".jpg"),System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}
}
使用集成的插值库加速:
验证码
这里略过
重定向过程
Context.Response.Redirect(“xxx.ashx”)
302重定向
重定向是两个请求,第一个请求后 服务端的响应报文里返回了一个特殊指令—302重定向指令。
文件下载
WebForm简介
一般处理程序 ashx不涉及复杂的页面的时候还可以,涉及到复杂页面的时候就太麻烦了,这时候微软给我们提供了一个叫 webform
AutoEventWireUp
IsPostBack分析
第四天
webform技术
… …
Request其他成员
可以用来做防盗链等其他的东西。
Response成员:
Response.Buffer设置为true以后,
Thread.Sleep(2000);
Response.write不会立刻输出,而是会等一会儿
ViewState使用与原理
无状态的根本原因是,浏览器和服务器使用Socket通信,服务器将请求结果返回给浏览器后,会关闭当前Socket连接。而且服务器会在处理页面完毕后销毁页面对象。
应用层面的原因是:浏览器和服务器之间通信都遵守HTTP协议。
一个浏览器发出的请求都是由实现了IHttpHandler接口的对象进行相应,由于下次访问不一定还是上次那个对象进行响应,上次响应完毕对象可能已经被销毁了,写的类变量中早就不存在,因此不要将状态信息保存到类中。
ViewState是一个键值对
Server成员:
Server属性
Server属性是HttpServerUtility的一个实例,它提供对服务器上的方法和属性的访问。
Server对象
Server.MapPath();
Server.Execute(“../NewList.aspx”);
在一个页面中执行另一个页面,
类似于iframe
但iframe不利于SEO优化。
Server.Transfer(“../NewList.aspx”);
跟excute差不多,但是URL是后者。
Redirect是先返回一个302,再发过去,
Transfer是直接跳转了。
HtmlEncode
HtmlDecode
关闭请求验证:
第五天
Cookie介绍
Url重写:伪静态
aaa.aspx?a==11-àaaa_111.aspx
cookie:一小段文本,明文。存储在客户端的浏览器内存里面或者磁盘。cookie是跟网站相关。百度可以往客户端写cookie,sina也可以写cookie,但是百度只能读取跟百度网站相关的cookie。
cookie会随着请求网站一块发送到后台【如果请求百度的时候,那么酒吧百度的cookie放到请求报文里面去,然后发送到后台。】
cookie可以设置一个Path来限制某个路径下面的页面+会把cookie发送到后台。
比如:请求图片,请求一个css、js,为了提高性能,可以通过path设置页面的所在路径,控制cookie的发送。
Cookie的域:浏览器往后台发送数据时候,要把cookie放到请求报文里面去,发送到后台,那么有个问题:请求是子域的网页,那么主域的cookie会不会发送到后台呢?
答案:是的。一块发送。如果请求时主域页面,子域的cookie时不会发送到后台的。
如果子域想让请求主域页面的时候也一块发送到后台,设置当前Cookie的域为主域就可以了。
cookie时通过响应报文的方式写到前台。最终写入Cookie时通过响应报文头来的
cookie有限制(大多数浏览器)
【response.cookie】
请求处理模型3
Cookie文档分析
回顾
IIS请求流程:
第六天
复习请求处理过程
JSON简介
…
第七天
…
第八天
Cache
自定义缓存:
依赖项:数据库改变后通过通知缓存,来更改销毁缓存。
页面缓存(一般给网站首页做)
数据源缓存(依赖于Webform中的一个控件,了解,并没有什么卵用)
文件缓存依赖
监视文件是否有变化,然后进行操作
进程外Session
应对集群时在不同的服务器上Session的存储的问题
数据库缓存依赖
监视数据库中的表是否有变化,然后进行操作
ajax控件
…
错误页配置与网站发布
网站发布NTFS(FAT32)
右键、发布。 这样会生成DLL,更安全,就不会被看到源代码了。
发布完后打开IIS部署网站。
在IIS上修改404页面也可以。
HttpModule
Global文件
//在线人数统计
最后一天
复习
Application对象
Application对象生存期和Web应用程序生存期一样长,生存期从Web应用程序网页被访问开始,HttpApplication类对象Application被自动创建,直到没有一个网页被访问时结束,Application对象被自动撤销。因此Application对象中的变量也有相同生存期,并且变量可以被Web应用程序中的所有网页访问。因此,可以在Application对象中建立一些全局的公用变量,由于存储在Application对象中的数值可以被应用程序的所有网页读取,所以Application对象的属性也适合在应用程序的网页之间传递信息。
Application对象主要有以下用途:
关于 ASP.NET 的 Application 的用法,与 Session 非常不同。下面来看看详细的介绍:
Session的用法
一、Session.Add 名称相同时,不会重复,而是覆盖。
1 2 3 |
|
二、名称忽略大小写。
1 2 |
|
三、Session Add 后立刻就可取到值(Remove 同理),这点不同于 Cookie,Cookie 要等到下个页面才有。
1 2 |
|
四、存储的 Session 数据类型为 object,最好用 Convert 转换。
1 |
|
如果转换为 string 最好用 Convert.ToString(),而不是 Session["s1"].ToString(),因为如果 Session 为 null,用后法就会报错。
五、在类中使用 Session。
1 |
|
Application 的用法
名称重复问题
1 2 3 4 5 6 7 8 |
|
如上代码,结果我们在备注中列出了。可以看出 Application 遇到键值相同,它既不报错,也不覆盖之前的,而是同时存在。用键值名称去取值时,取到的是同名中第一个对应的值。如果非要取后面的,就用 index。
如果我们要遇相同 name,就覆盖,可用下面的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
上面代码中,直接修改 obj 是行不通的,但是遇到对象的话,如下代码是行得通的。说明:这是 C# 值引用、地址引用的知识点,与 Application 无关。
1 |
|
委托与文件流复习
聊天程序(基于Socket,Thread)
简单回顾委托
·什么是委托?(安全的函数指针)
通俗:就是一个能存放符合某种格式(方法签名)的方法的指针的清单。
指针指向内存的地址,安全的函数指针是指—不会指向操作系统的内存地址。(和C语言中的指针不太一样)。
·委托创建方式
准备一个方法: string Hello U(string uName) (//方法代码)
声明委托: delegate 返回值类型 委托类型名(参数)
例子: delegate string DGSayHi(string uName);
创建委托对象: DGSayHi dgSay = new DGSayHi(HelloU);
或者: DGSayHi dgSay = HelloU;
追加方法: dgSay += HelloU2//Delegate. Combine(,)
删除方法: dgSay -+ HelloU3
·委托调用方法
dgSay(“binggo”), //dgSay.Invoke(“binggo”)
·委托和事件的关系。
委托是一个类。
事件是一个对象。
事件是委托的一个实例
事件是安全的,委托是不安全的。
因为委托是一个类,事件是一个对象,所以事件只能在代码内进行调用,而委托不能。
文件流 FileStream
string filePath = openfile.FileName;
using(FileStream fileStream = new FileStream(filePath,FileMode.Open,FileAccess.Read))
{
byte[] buffer = new byte[fileStream.length];
fileStream.Read(buffer,0,buffer.Length);
string str = System.Text.Encoding.UTF8.GetString(buffer);
this.textBox1.Text = str;
}
线程与进程的概念
(1) 进程概念:是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。进程之间是相对独立的,一个进程无法直接访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行,Windows系统就是利用进程把工作划分为多个独立的区域的。进程可以理解为一个程序的基本边界。
Process.Start(“notepad.exe”,”a.txt”);
(2) 线程概念。 是Windows 任务调度的最小单位。线程是程序中的一个执行流。
解决问题:进程是一个资源的拥有者,因而在进程的创建、撤销、和切换的过程中,系统必须为之付出较大的时空开销,限制了并发程序的进一步提高。
所有代码都必须执行在线程。有线程才能有代码执行。
(3) 单线程问题:
(4) 创建线程,以及线程的属性
Priority
Name
Abort
Thread.Join(1000):主线程会阻塞等待 thread实例指向的线程,如果在1000ms内,thread线程执行完成了的画,那么主线程就立即往下执行。如果超过那么也往下执行
线程应用场景:
(1)希望或等更多操作系统资源尽快处理我们的业务,缩短处理的时间。
问题:一个线程执行需要10s ,分成两个线程:10s? 因为不断切换,实际上大于了10s,
可是为什么说多线程提升了效率呢? 因为线程调度的问题,
在一个操作系统中,同时可能有1000个线程在运行,如果一个进程有很多线程,
因为CPU在不断的切换,那么这个程序被调度的概率就增大了。
(2):如果一个如果一个非常复杂的操作。需要占用非常长的时间。而WinForm又不允许阻塞UI线程。
后台线程
myThread.IsBackground = true
当程序或窗体关闭的时候应用程序也关闭,就是后台线程
要是不关闭就叫前台线程,所以一般我们都用后台线程!
线程执行带参数的方法
List<int> list = new List<int >{1,2,3,4,5,6};
ParameterizedThreadStart threadStart = new ParameterizedThreadStart(Show);
Thread thread1 = new Thread(threadStart);
thread1.IsBackground = true;
thread1.Start(list);
private void Show(object obj);
{
List<int>list = (list<int>)obj
foreach(int i in list)
{
MessageBox.Show(i.ToString());
}
}
5:跨线程访问
Thread thread2 = new Thread();
thread2.IsBackground = true;
thread2.Start()
上面这种方法不太专业,
建议使用另一种方法Invoke:
进程
ThreadStart threadStart = new ThreadStart(StartCaul); //这是一个委托
Thread myThread = new Thread(threadStart);
myThread.Name = “shit”;
myThread.Priority = ThreadPriority.Highest;//线程的优先级
//myThread.Abort();这是一种很暴力的终止线程的方法
myThread.Start();//将线程设为运行状态。
myThread.join(1000); 阻塞1000ms
/*
thread.Join(1000)
主线程会阻塞等待 thread实例指向的线程,如果在1000ms内,thread线程执行完成了的话,那么主线程就立即往下执行。如果超时那么也往下执行。
*/
private void StartCaul()
{
… …
}
线程同步与线程池
Thread thread3 = new Thread(GetResult);
thread3.IsBackground = true;
thread3.Start();
private void GetResult()
{
int a = 0;
for(int I = 0; i<9999999;i++)
{
a=I;
}
if(this.textBox1.InvokeRequired)//判断一下textbox是否在创建它的以外的线程访问
{
this.textBox1.Invoke(new Action<string,TextBox>(SetValue))
}
}
private void SetValue(string txt,TextBox tb)
{
}
线程同步
用锁:
线程池
·线程切换消耗资源,cpu在切换线程的时候,需要把当前线程执行的状态保持到寄存器里面去。
·线程创建非常消耗资源。线程创建非常慢,占用了大量的内存空间。每个线程最少1M内存开销。
线程池:提高了线程的利用率,非常适合工作任务非常小,而且又需要使用单独的线程来解决的 问题。
什么时候用线程池?什么时候用手动创建线程?
1、 能用线程池就用线程池
2、 我们想手动关闭现成的话那么必须手动创建了。Abort() Join()
3、 我们需要对线程池的线程的优先级做设置的情境下,只能使用手动创建线程。
4、 如果执行的线程执行时间特别长。建议手动创建线程
Socket相关概念
socket是一种进程通信机制
端口的分类
(1) 公认端口:从0到1023,它们紧密绑定(binding)于一些服务。通常这些端口的通讯明确表明了某种服务的协议。例如:80端口实际上总是HTTP通讯。
(2) 注册端口:从1024到49151.它们松散地绑定于一些服务。也就是说有许多服务绑定于这些端口,这些端口同样用于许多其他目的。例如:许多xitong处理动态端口从1024左右开始。
(3) 动态和/或私有端口:从49152到65535。理论上不应为服务分配这些端口。
…
标签:ret mod .exe multi 用途 rtc fromfile dal 场景
原文地址:https://www.cnblogs.com/eret9616/p/8747493.html