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协议、线程、线程池的更多相关文章

  1. 常量,字段,构造方法 调试 ms 源代码 一个C#二维码图片识别的Demo 近期ASP.NET问题汇总及对应的解决办法 c# chart控件柱状图,改变柱子宽度 使用C#创建Windows服务 C#服务端判断客户端socket是否已断开的方法 线程 线程池 Task .NET 单元测试的利剑——模拟框架Moq

    常量,字段,构造方法   常量 1.什么是常量 ​ 常量是值从不变化的符号,在编译之前值就必须确定.编译后,常量值会保存到程序集元数据中.所以,常量必须是编译器识别的基元类型的常量,如:Boolean ...

  2. GIL 线程/进程池 同步异步

    GIL 什么是GIL 全局解释器锁,本质是一把互斥锁,是加在cpython解释器上的一把锁, 同一个进程内的所有线程需要先抢到GIL锁,才能执行python代码 为什么要有GIL cpython解释器 ...

  3. 子进程回收资源两种方式,僵尸进程与孤儿进程,守护进程,进程间数据隔离,进程互斥锁,队列,IPC机制,线程,守护线程,线程池,回调函数add_done_callback,TCP服务端实现并发

    子进程回收资源两种方式 - 1) join让主进程等待子进程结束,并回收子进程资源,主进程再结束并回收资源. - 2) 主进程 “正常结束” ,子进程与主进程一并被回收资源. from multipr ...

  4. Linux线程的实现 & LinuxThread vs. NPTL & 用户级内核级线程 & 线程与信号处理

    另,线程的资源占用可见:http://www.cnblogs.com/charlesblc/p/6242111.html 进程 & 线程的很多知识可以看这里:http://www.cnblog ...

  5. C#线程 线程进阶

    第四部分:高级线程 非阻塞同步 前面我们说过,即使在分配或增加字段的简单情况下,也需要同步.尽管锁定始终可以满足此需求,但是竞争性锁定意味着线程必须阻塞,从而遭受上下文切换的开销和调度的延迟,这在高度 ...

  6. Linux线程 之 线程 线程组 进程 轻量级进程(LWP)

    Thread Local Storage,线程本地存储,大神Ulrich Drepper有篇PDF文档是讲TLS的,我曾经努力过三次尝试搞清楚TLS的原理,均没有彻底搞清楚.这一次是第三次,我沉浸gl ...

  7. JAVA之旅(十五)——多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止

    JAVA之旅(十五)--多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止 我们接着多线程讲 一.生产者和消费者 什么是生产者和消费者?我们 ...

  8. python 进程和线程-线程和线程变量ThreadLocal

    线程 线程是由若干个进程组成的,所以一个进程至少包含一个线程:并且线程是操作系统直接支持的执行单元.多任务可以由多进程完成,也可由一个进程的多个线程来完成 Python的线程是真正的Posix Thr ...

  9. 进程?线程?多线程?同步?异步?守护线程?非守护线程(用户线程)?线程的几种状态?多线程中的方法join()?

    1.进程?线程?多线程? 进程就是正在运行的程序,他是线程的集合. 线程是正在独立运行的一条执行路径. 多线程是为了提高程序的执行效率.2.同步?异步? 同步: 单线程 异步: 多线程 3.守护线程? ...

随机推荐

  1. hadoop2.2编程:序列化

    测试序列化后的长度 提示:需要用到的类,以及继承关系如下: 1.java.lang.Object |__ java.io.OutputStream |__ java.io.ByteArrayOutpu ...

  2. 如何修复在Microsoft Azure中“虚拟机防火墙打开,关闭RDP的连接端口”问题

     注:下列步骤并不一定适用所有场景,提供思路,请灵活应用 我们在使用Microsoft Azure 中Windows 虚拟机,有时会发生错误打开防火墙或一些管家软件错误的关闭了"远程桌面 ...

  3. ruby脚本打印日志到rspec的报告文件中

    在通过ruby+webdriver+rspec做自动化测试的时候,为了便于观察用例执行情况,我基本上都会用 rspec XX.rb --format doc -o result.log 如果遇到失败的 ...

  4. Android开发必知--几种不同对话框的实现

    在开发过程中,与用户交互式免不了会用到对话框以实现更好的用户体验,所以掌握几种对话框的实现方法还是非常有必要的.在看具体实例之前先对AlertDialog做一个简单介绍.AlertDialog是功能最 ...

  5. Hibernate criteria 混合sql语句多表关联时查询注意事项

    直接进入正题 假设有一个实体类 /** * 产品分类 */ public class ProductType{ @Id private String no;//编号 private String na ...

  6. 使用python爬取P站图片

    刚开学时有一段时间周末没事,于是经常在P站的特辑里收图,但是P站加载图片的速度比较感人,觉得自己身为计算机专业,怎么可以做一张张图慢慢下这么low的事,而且这样效率的确也太低了,于是就想写个程序来帮我 ...

  7. flushall()函数的用法

    flushall()函数 如下所示的一个非常简单的程序. #include void main(void) { char cA,cB; printf("input cA and cB:\n& ...

  8. patch与diff的恩怨

    一.概述 diff和patch是一对相辅相成的工具,在数学上来说,diff类似于对两个集合的差运算,patch类似于对两个集合的和运算.diff比较两个文件或文件集合的差异,并记录下来,生成一个dif ...

  9. [转]mysql 5.6 存储过程+事务+游标+错误异常抛出+日志写入

    转自:http://www.wolonge.com/post/detail/118249 DELIMITER $$ USE `ecstore`$$ DROP PROCEDURE IF EXISTS ` ...

  10. Java_Web 连接池

    对于共享资源,有一个很著名的设计模式:资源池(Resource Pool).该模式正是为了解决资源的频繁分配﹑释放所造成的问题.为解决我们的问题,可以采用数据库连接池技术.数据库连接池的基本思想就是为 ...