多线程与Socket编程
一、死锁
定义:
指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。 由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象:死锁.
解决办法:
1.有序资源分配法
申请不同类资源时,必须按各类设备的编号依次申请
2 .银行家算法
检查申请者对资源的最大需求量,如果系统现存的各类资源可以满足申请者的请求,就满足申请者的请求。
二、线程池ThreadPool
可用于发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器。线程池允许在后台运行多个工作,而不需要为每个任务频繁地创建和销毁单独的线程,从而减少了开销.
*注意*
线程池中的线程都是后台线程
不能手动设置每个线程的属性,比如设置为前台线程、优先级等等
当执行一些比较短的任务是考虑使用线程池,长时间执行的任务不要使用线程池来创建,而要使用Thread手动创建一个线程。
三、委托的异步调用
BeginInvoke 异步调用,BeginInvoke(被调用的方法的参数,回调函数,回调函数的参数);
EndInvoke 获取异步调用的(方法)返回值
IAsyncResult 异步操作的状态
AsyncResult 异步操作的结果(可以获取当前执行的委托对象)
using System.Runtime.Remoting.Messaging;
AsyncState获取回调函数的参数。
注意:委托的异步调用只对单播委托\
四、网络协议
网络五层:应用层、传输层、网络层、链路层、物理层。一般因特网现在都是用的是五层协议,把表示层与会话层的功能都交给了具体的应用程序来做了。
网络七层:应用层、表示层、会话层、传输层、网络层、链路层、物理层
1.应用层:(HTTP、FTP、SMTP)报文Message
2.表示层:通信的应用程序能够解释交换数据的含义。数据压缩、加密解密、数据描述等。
3..会话层:定义了数据交换的定界、同步、建立检查点等功能,例如如何开始、控制结束一个会话。保证接收消息的连续性,完整性。
4.传输层(TCP、UDP)报文段Segment,为运行在不同主机上的应用程序进程间提供数据传输服务。通过套接字(Socket)实现。
a>TCP(传输控制协议)面向连接的、可靠(应用:ftp、smtp、http等都是基于tcp)
B>UDP(用户数据报协议)无连接的、不可靠的(数据报)应用:视频会议、网络电话、DNS解析。(速度快,能容忍部分数据丢失)
5.网络层(IP)数据报datagram,把数据从一台主机移动到另一台主机,主机间通信。IP协议不可靠,有丢包。
6.链路层(以太网、WiFi、点对点)帧Frame,负责将数据报传递给下一个节点。不同的链路层有特定的链路层协议。一系列路由器、交换机。
7.物理层:负责把数据一个bit一个bit的从一个节点移动到下一个节点,该层中的协议仍然与链路层相关。例如,以太网具有许多物理层协议:双绞铜线的、同轴电缆的、光纤的。
网络简单的四层
应用层 (Application):应用层是个很广泛的概念,有一些基本相同的系统级 TCP/IP 应用以及应用协议,也有许多的企业商业应用和互联网应用。
传输层 (Transport):传输层包括 UDP 和 TCP,UDP 几乎不对报文进行检查,而 TCP 提供传输保证。
网络层 (Network):网络层协议由一系列协议组成,包括 ICMP、IGMP、RIP、OSPF、IP(v4,v6) 等。
链路层 (Link):又称为物理数据网络接口层,负责报文传输。
网络层协议
TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,需要建立连接(像手机)
UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议,只管发送(像电报)。它是属于TCP/IP协议族中的一种。
TCP/IP 连接需要三次握手
1.确定a能发给b
2.b告诉a接受能破解,b能发给a数据
3.a告诉b能破解
端口
1.用来修饰同一地址内的,不同的程序的
2.一个端口同以时间只能被一个程序所监听
3.一个程序绑定一个独有的端口
socket
socket的英文原义是“孔”或“插座”。作为进程通信机制,取后一种意思。通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。(其实就是两个程序通信用的。),是对网络层的抽象,方便客户端和服务端的传输
1.定义:进程通信机制,通常称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。
2.端口范围:0-65535之间。端口的意义:用来区分不同的进程。
分类
(1)公认端口:(Well Known Ports):从0到1023,它们紧密绑定(binding)于一些服务。通常这些端口的通讯 明确表明了某种服务的协议。例如:80端口实际上总是HTTP通讯,ftp21,smtp25,....。
(2)注册端口(Registered Ports):从1024到49151。它们松散地绑定于一些服务。也就是说有许多服务绑定于 这些端口,这些端口同样用于许多其它目的。例如:许多系统处理动态端口从1024左右开始。
(3)动态和/或私有端口(Dynamic and/or Private Ports):从49152到65535。理论上,不应为服务分配这些端 口。实际上,机器通常从1024起分配动态端口。但也有例外:SUN的RPC端口从32768开始。
3.两种类型:
a.流式Socket(STREAM): 是一种面向连接的Socket,针对于面向连接的TCP服务应用,安全,但是效率 低;发送数据是以流的方式,发送方可以有自己的缓冲区大小,接收方也可以有自己的缓冲区大小,不必一致,只要发送的数据都接收到就可以了。一次发10个字节,发3次。接收方一次接6个字节,接5 次。只要保证最后是完整的就可以。
b.数据报式Socket(DATAGRAM): 是一种无连接的Socket,对应于无连接的UDP服务应用.不安全(丢失,顺序混乱,在接收端要分析重排及要求重发),但效率高.发送方每次发送一个数据报,接收方必须一次也接收一个完整的数据报。
创建和使用socket
//第一步:创建socket:第一个参数:设置网络层的协议,第二个参数设置传输数据的方式,第三个参数:传输层的协议
Socket listenSocket=new Socket(AddressFamily.InterNetwor,SocketType.Stream,ProtocolTypt.Tcp);
//第二步:绑定一个端口和Ip地址
//根据字符串创建一个ip地址对象
IpAddress ip=IpAddress.parse(this.txtIp.Text);//127.0.0.1
//创建一个节点
IpEndpoint endpoint =new IpEndpoint(ip,int.Parse(this.txtport.Text));
listenSocket.Bind(endpoint);
//第三步:开始监听端口
listensocket.Listen(10);//连接队列的最大数
//第四步:开始接受用户的连接
//Accept会阻塞主线程,直到客户端连接上来后,方法执行完成并返回代理Socket
Socket proxSocket=listenSocket.Accept();
//给客户端传输一个字符串
var buffer =Encoding.Default.GetBytes("asdf ");
proxSocket.Send(buffer);
六、Socket编程模型
服务器端:
1.创建Socket对象。设置协议、传输方式等(连接Socket)
2.绑定IP与端口(设置要监听的IP与端口)。Bind()
3.开启监听。Listen()
4.开始接受客户端连接。Accept();//阻塞线程,同时也需要循环不断接受用户连接。
5.接受了客户端的连接,生成一个新的Socket对象(通信Socket)
6.接受(Receive)和发送(Send)消息//需要循环不断接收用户的消息
7.Shutdown()禁用发送与接收功能。
8.Close()关闭释放资源
客户端:
1.创建Socket对象。设置协议、传输方式等(连接Socket)
2.Connect()连接服务器(IP与端口)
3.向服务器发送、接受消息
4.Shutdown()禁用发送与接收功能。
5.Close();关闭释放资源
HttpHandler(一般处理程序)
HttpHandler是一个实现了IHttpHandler接口的特殊类。任何一个实现了IHttpHandler接口的类,是作为一个外部请求的目标程序的前提。如果是没有实现这个接口的类,就不能被浏览器请求。我们可以通过创建一个我们自己的HttpHandler程序来生成浏览器代码,发送回客户端浏览器!当我们不需要返回过多的Html代码的时候可以使用它哦 (.ashx)
IHttpHandler的定义是这样的:
...public interface IHttpHandler
{
...bool IsReusable{get;}
...void ProcessRequest(HttpContext context);
}
其中ProcessRequest就是我们处理请求的主要代码;
IsReusable属性用来表示在IHttpHandlerFactory对象创建IHttpHandler的时候是否能够将这个Handler存入池中以便重用。
IHttpHandlerFactory的定义是这样的:
...public interface IHttpHandlerFactory
{
...IHttpHandler GetHandler(HttpContext context,string requestType,string url,string pathYranslated);
...void ResaseHandler(IHttpHandler handler);
}
GetHandler(),返回实现了IHttpHandler接口的类的实例。
ReleaseHandler(),使得Factory可以重复使用一个已经存在的Handler实例
案例:使用HttpHandler实现图片防盗链
public void ProcessRequest(HttpContext context){
context.Response.ContentType="text/plain";
//获取文件服务器端物理路径
string FileName=context.Server.MapPath(context.Request.FliePath);
//如果UrlReferrer为空,则显示一张默认的禁止盗链的图片
if(context.Request.UrlReferrer.Host==null)
{
context.Response.ContentType="image/JPEG";
context.Response.WriteFile("/error.jpg");
}
//如果urlRefferrer中不包含自己站点的主机域名,则显示一张默认的禁止盗链的图片
else
{
if(coontext.Request.UrlReferrer.Host.IndexOf("hezhiqiang.com")>0)
{
context.Respones.ContentType="image/JPEG";
context.Response.WriteFile(FileName);
}
else
{
context.Respones.ContentType="image/JPEG";
context.Response.WriteFile("/error.jpg");
}
}
}