Http协议、线程、线程池
Socket模拟服务端运行代码:
1:启动服务端监听的服务,并接受客户端的连接
1.1 创建Socket
Socket listenSocket=new Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp);
1.2绑定端口和ip地址
IPAddress ip = IPAddress.Parse(this.txtIp.Text);
IPEndPoint endPoint=newIPEndPoint(ip,
int.Parse(this.txtPort.Text));
listenSocket.Bind(endPoint);
1.3开始监听
2:启动开始接受客户端连接的线程,开始接受客户端的连接工作。
Accept会阻塞当前主线程(用到多线程),直到有客户端连接上来,并返回 具体通信的Socket。我们必须让当前的监听的Socket不断地执行Accept方 法(放到while循环 中)才能够拿到通信的Socket。
proxSocket 就是负责跟具体一个客户端的通信,可以通过proxSocket 拿 到远程客户端 的ip和端口。
Socket proxSocket = listenSocket.Accept();
3: 服务器端不停的监听客户端的发送来的消息。
proxSocket.Receive();
Receive:能阻塞执行此代码的线程。创建一个不断接受客户端连接发送来的消息的线程. 而且Receive方法跟流中Read非常相似,每次读取操作都是从上次读取的节点处继续往 下读取数据。
Int realLen = proxSocket.Receive(buffer);//返回值是一个具体收到的字节数.可以通过 realLen的长度来半段客户端是否有信息返回,如果realLen的值为0, 代表客户端 退出 的一个信号关闭Socket ,关闭当前的Socket接受数据的线程在客户端集合中移除掉当的 代理对象。
proxSocket.Shutdown(SocketShutdown.Both);
proxSocket.Close();//关闭当前的Socket对象
客户端:socket 如果直接关闭的话,可以直接通过异常来捕捉
但是如果是通过shutdown的话,本地客户端不会立即关闭,而是往服务端发送空包,表示
自己已经关闭,并等待服务端响应,会等一定的时间,超时后再关闭socket。
服务端:可以通过获取的包的长度是0,也就是空包,则直接退出循环,并关闭socket
扩展(发信息,抖动,文件,)
发送数据中:第一个字节如果是0,代表字符串
如果是1:代表闪屏
如果是2:代表文件
给数据数组添加 数据类型的标志位
byte[] realData = new byte[data.Length +1];
realData[0] = 0;设置是字符串类型
把一个块拷贝到另外一个
Buffer.BlockCopy(data,0,realData,1,data.Length);
客户端连接服务器:
1.创建Socket
clientSocket=newSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);直接连接服务器:只要下面的方法连接服务没有出现异常,那么就代表连接成功。
clientSocket.Connect(IPAddress.Parse(this.txtIp.Text),int.Parse(this.txtPort.Text));
2.接受服务器发送的消息:
创建新线程不断接受服务器发来的消息(首先判断第一个字节是0,1,2)
recieveThread = new Thread(new ParameterizedThreadStart(this.ProcessReciveData));
recieveThread.IsBackground = true;
recieveThread.Start(null);
3.窗体关闭之前,先关闭Socket
recieveThread.Abort();//关闭一直在接收数据的线程
if (clientSocket.Connected)
{
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
HTTP协议简单流程:
在浏览器中输入地址,将数据封装成了HTTP协议里面规定的请求数据的格式:
GET/Login/LogOn HTTp/1.1
Accept:text/html,application/xhtml+xml,*/*
Accept-Language:zh-CN
User-Agent:MOzilla/5.0(compatible;MSIE 9.0);
Qdesk 2.5.1270.201; Windows NT 6.1; Trident/5.0)
Accept-Encoding:gzip,deflate
Host:localhost:8094
Connection:Keep-Alive
Cookie:txtName=ertertre;
通过Socket发送到服务端,服务端对报文经行解析,处理,响应,再发送到客户端,
客户端解析响应保温,然后渲染html页面和css,js等;
托管和非托管
托管:中间代码交给clr解析成编译成操作系统能识别的二进制码的代码
非托管:直接将二进制码交给操作系统化内核执行的代码
线程:
初始化线程非常消耗资源(显示的东西少时,不建议创建线程,可以用线程池)
前台和后台线程
1.默认线程是一个主线程,是一个前台线程
2.前台线程都执行完毕才能结束进程
3.一般情况下使用的线程的时候都要用后台线程
线程的一些方法
1.设置后台线程
thread.IsBackground=true;//如果设置为true表示当前线程为后台线程:当程序中所有的前台线程都退出之后,那么主进程就退出了,后台线程不阻塞退出
2.给线程取名
thread.Name="给开发人员用的,用来区分不同的线程";
3.准备好,让操作系统执行
thread.Start();//只是告诉操作系统:我怎备好了
4.建议的设置线程的优先级(具体还的由操作系统决定,操作系统的线程优先级是最高的)
thread.priority=Threadpriority.AbveNormal;//给当前线程设置一个优先级
5. 关闭线程 (关闭的线程就不能在重新进行使用)
第一种
这种一般是在线程中出现了异常,正常情况不能关闭的时候(不建议使用)
出现异常的时候会很大的影响程序的性能(这个关闭就不能在使用了)
thread.Abort();//直接关闭线程:内部会抛出一个异常,尽量不要用,这样会导致系统内部抛出异常,但不会导致程序崩溃,clr帮我们捕获了此异常
第二种
控制信号体关闭线程,即设置一个标签控制线程的停止,而不是调用上面的那个方法,这样线程还能进行使用
6.设置等待时间
Thread.Sleep(2000);
7.主线程等待子线程结束后在执行,可以填写参数规定等待时间
thread.Join();//那个线程调用此方法,就让哪个线程等待thread线程。
8.得到当前线程的id号
Thread.currentThread.ManagedThreadId;
线程的使用
1.线程的简单的写法
new Thread(()=>
{
Console.writeLine("ddd");
}).Start();
2.带参数的线程
2.1传入委托的类型
ParameterizedThreadstrt
//pubic delegate void ParameterizedThreadStart(object obj);
2.2实例化一个
Thread thread=new Thread(delegate(object obj){ Console.writeLine(obj.Tostring());});
2.3通过start方法给委托传值
thread.start(4);
异步委托(使用的是线程池)
异步委托就是相当于创建一个新的线程执行这个委托,因为创建一个线程的时候,委托的类型的固定的,异步委托,委托类型由自己决定,而且这个线程由线程池提供(是后台线程)节省资源
异步委托的使用
第一种
1.声明一个委托类型
public delegate int AddDel(int a,int b);
2.定义一个这种委托类型的方法
static int AddDemo(int a, int b)
{
return a+b;
}
3.让这个委托类型方法异步
AddDel addDel=new AddDel(addDemo);
//addDel(4,5);//这样是由当前执行此代码的线程执行 委托指向的方法
var result= addDel.BeginInvoke(4,5,null,null);//启动一新线程【后台线程,此线程由线程池提供】,新的线程回调函数指向委托的方法
//new Tread(AddDemo)
4.Result是异步委托中的一些信息
//去拿另外一个线程执行方法的结果
int retval=addDel.EndInvoke(result);//阻塞当前主线程,直到子线程执行完成并返回值。
第二种
1.在异步中获取返回值 (异步委托函数运行完,执行回调函数)
addDel.BeginInvoke(5,6,new AsyncCallback(ProcessAfterFunExcute),"s")
2.回调函数的过程:把上边异步方法的返回值的相关的信息,传入到回调函数中作为参数
static void ProcessAfterFunExcute(IAsyncResult result)
{
//在异步的委托的方法执行完成之后,自动来调用此方法。调用此方法的线程是新的线程
AsyncResult funAsyncResult=(AsyncResult) result;
AddDel del=(AddDel) funAsyncResult.AsyncDelegate;//拿到异步的委托的实例
var retval=del.EndInvoke(funAsyncResult);
3.打印"s"
//拿到传来的值
Console.writeLine(funAsynResult.Asyncstate.Tostring());
并发和异步
并发:同一时间执行一个代码或动作
异步:并不是并发,是时间片轮转
摇奖
动态创建的控件默认只能由创建他的线程使用,但是可以设置,别的线程访问
//禁止 线程操作控件进行检查
Control.checkForIllegalCrossThreadCalls=false;
也可以不设置检查,进行判断(专业的方式,判断当前的控件是否是当前的线程创建的)
用invoke方法
foreach(var label in lbList)
{
if(label.InvokeRequired)//InvokeRequired属性就是帮我们判断当前线程跟控件之间的关系,如果为true 代表:当前控件不是线程创建的,那么需要进行invoke。如果为false,那么代表当前控件就是当前线程创建的,直接用就行了,不需要Invoke
{
//invoke方法对控件的操作
label.Invoke(new Action<Label,string>(this.setText),label,r.Next(0,10).ToString());//invoke后面的传来的方法体,由创建Lable的线程执行
}
else
{
//如果当前lable控件就是执行当前代码的线程创建的话,没问题的
label.Text=r.Next(0,10).ToString();
}
、、Control:跨线程方法,使用第一种方式,禁止校验跨线程访问的方式
}
Thread.Sleep(100);
线程池
线程池:为了提高线程使用效率,节省创建线程消耗的资源,提高线程重复利用率,避免用户适应的线程每次都重新创建和分配线程
线程池的内部结构
包括,工作项队列(创建线程池时,传入的方法体委托其实放在工作项队列中,不使用的情况下是先进先出。但当调用到线程中执行后,工作项队列多种的委托执行的顺序就是不确定的,无序的),和线程(也包含线程的工作项队列,后进先出,当这个工作线程的栈空的时候,去公共的队列中去取几个工作项)
线程池的使用
Threadpool.QueueuserworkItem(0=>{console.writeLiine(o.Tostring());},“1”);
模拟对象池
生产者和消费者,利用lock的机制实现了同步,也就是一个线程在使用修改数据的时候别的线程不能使用,必须等解锁以后才能使用
生产消费内部实现的过程
在应用程序域的堆中,每个对象都有下面内容:类空间(自己的属性和方法,属于当前的对象),同步索引块(默认为-1,有了lock后相当于加上了一个索引值,指向同步索引数组中的一个变量,lock结束又变回-1),类型指针(每个类的实例的类型指针指向的类型对象,指向类型信息)
Http协议、线程、线程池的更多相关文章
- 常量,字段,构造方法 调试 ms 源代码 一个C#二维码图片识别的Demo 近期ASP.NET问题汇总及对应的解决办法 c# chart控件柱状图,改变柱子宽度 使用C#创建Windows服务 C#服务端判断客户端socket是否已断开的方法 线程 线程池 Task .NET 单元测试的利剑——模拟框架Moq
常量,字段,构造方法 常量 1.什么是常量 常量是值从不变化的符号,在编译之前值就必须确定.编译后,常量值会保存到程序集元数据中.所以,常量必须是编译器识别的基元类型的常量,如:Boolean ...
- GIL 线程/进程池 同步异步
GIL 什么是GIL 全局解释器锁,本质是一把互斥锁,是加在cpython解释器上的一把锁, 同一个进程内的所有线程需要先抢到GIL锁,才能执行python代码 为什么要有GIL cpython解释器 ...
- 子进程回收资源两种方式,僵尸进程与孤儿进程,守护进程,进程间数据隔离,进程互斥锁,队列,IPC机制,线程,守护线程,线程池,回调函数add_done_callback,TCP服务端实现并发
子进程回收资源两种方式 - 1) join让主进程等待子进程结束,并回收子进程资源,主进程再结束并回收资源. - 2) 主进程 “正常结束” ,子进程与主进程一并被回收资源. from multipr ...
- Linux线程的实现 & LinuxThread vs. NPTL & 用户级内核级线程 & 线程与信号处理
另,线程的资源占用可见:http://www.cnblogs.com/charlesblc/p/6242111.html 进程 & 线程的很多知识可以看这里:http://www.cnblog ...
- C#线程 线程进阶
第四部分:高级线程 非阻塞同步 前面我们说过,即使在分配或增加字段的简单情况下,也需要同步.尽管锁定始终可以满足此需求,但是竞争性锁定意味着线程必须阻塞,从而遭受上下文切换的开销和调度的延迟,这在高度 ...
- Linux线程 之 线程 线程组 进程 轻量级进程(LWP)
Thread Local Storage,线程本地存储,大神Ulrich Drepper有篇PDF文档是讲TLS的,我曾经努力过三次尝试搞清楚TLS的原理,均没有彻底搞清楚.这一次是第三次,我沉浸gl ...
- JAVA之旅(十五)——多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止
JAVA之旅(十五)--多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止 我们接着多线程讲 一.生产者和消费者 什么是生产者和消费者?我们 ...
- python 进程和线程-线程和线程变量ThreadLocal
线程 线程是由若干个进程组成的,所以一个进程至少包含一个线程:并且线程是操作系统直接支持的执行单元.多任务可以由多进程完成,也可由一个进程的多个线程来完成 Python的线程是真正的Posix Thr ...
- 进程?线程?多线程?同步?异步?守护线程?非守护线程(用户线程)?线程的几种状态?多线程中的方法join()?
1.进程?线程?多线程? 进程就是正在运行的程序,他是线程的集合. 线程是正在独立运行的一条执行路径. 多线程是为了提高程序的执行效率.2.同步?异步? 同步: 单线程 异步: 多线程 3.守护线程? ...
随机推荐
- hadoop2.2编程:序列化
测试序列化后的长度 提示:需要用到的类,以及继承关系如下: 1.java.lang.Object |__ java.io.OutputStream |__ java.io.ByteArrayOutpu ...
- 如何修复在Microsoft Azure中“虚拟机防火墙打开,关闭RDP的连接端口”问题
注:下列步骤并不一定适用所有场景,提供思路,请灵活应用 我们在使用Microsoft Azure 中Windows 虚拟机,有时会发生错误打开防火墙或一些管家软件错误的关闭了"远程桌面 ...
- ruby脚本打印日志到rspec的报告文件中
在通过ruby+webdriver+rspec做自动化测试的时候,为了便于观察用例执行情况,我基本上都会用 rspec XX.rb --format doc -o result.log 如果遇到失败的 ...
- Android开发必知--几种不同对话框的实现
在开发过程中,与用户交互式免不了会用到对话框以实现更好的用户体验,所以掌握几种对话框的实现方法还是非常有必要的.在看具体实例之前先对AlertDialog做一个简单介绍.AlertDialog是功能最 ...
- Hibernate criteria 混合sql语句多表关联时查询注意事项
直接进入正题 假设有一个实体类 /** * 产品分类 */ public class ProductType{ @Id private String no;//编号 private String na ...
- 使用python爬取P站图片
刚开学时有一段时间周末没事,于是经常在P站的特辑里收图,但是P站加载图片的速度比较感人,觉得自己身为计算机专业,怎么可以做一张张图慢慢下这么low的事,而且这样效率的确也太低了,于是就想写个程序来帮我 ...
- flushall()函数的用法
flushall()函数 如下所示的一个非常简单的程序. #include void main(void) { char cA,cB; printf("input cA and cB:\n& ...
- patch与diff的恩怨
一.概述 diff和patch是一对相辅相成的工具,在数学上来说,diff类似于对两个集合的差运算,patch类似于对两个集合的和运算.diff比较两个文件或文件集合的差异,并记录下来,生成一个dif ...
- [转]mysql 5.6 存储过程+事务+游标+错误异常抛出+日志写入
转自:http://www.wolonge.com/post/detail/118249 DELIMITER $$ USE `ecstore`$$ DROP PROCEDURE IF EXISTS ` ...
- Java_Web 连接池
对于共享资源,有一个很著名的设计模式:资源池(Resource Pool).该模式正是为了解决资源的频繁分配﹑释放所造成的问题.为解决我们的问题,可以采用数据库连接池技术.数据库连接池的基本思想就是为 ...