浅谈C#网络编程(二)

王朝学院·作者佚名  2016-08-28
窄屏简体版  字體: 小  |  中  |  大  |  超大  

阅读目录:

异步IO非阻塞式同步IO基于回调的异步IO并发异步IO上篇提到用多线程处理多个阻塞同步IO而实现并发服务端,这种模式在连接数量比较小的时候非常适合,一旦连接过多,性能会急速下降。 在大多数服务端网络软件中会采用一种异步IO的方式来提高性能。

同步IO方式:连接Receive请求->等待->等待->接收成功异步IO方式:连接Receive请求->立即返回->事件或回调通知采用异步IO方式,意味着单线程可以处理多个请求了,连接发起一个Receive请求后,当前线程可以立即去做别的事情,当数据接收完毕通知线程处理即可。

其数据接收分2部分:

数据从别的机器发送内核缓冲区内核缓冲区拷贝到用户缓冲区第二部分示例代码:

byte[] msg =newbyte[256]; socket.Receive(msg);

介绍这2部分的目的是方便区分其他几种方式。 对于用户程序来说,同步IO和异步IO的区别在于第二部分是否需要等待。

非阻塞式同步IO非阻塞式同步IO,由同步IO延伸出来,把这个名词拆分成2部分描述:

非阻塞式,指的是上节"数据从别的机器发送内核缓冲区"部分是非阻塞的。同步IO,指的是上节"内核缓冲区拷贝到用户缓冲区"部分是等待的。既然是第一部分是非阻塞的,那就需要一种方法得知什么时候内核缓冲区是OK的。 设置非阻塞模式后,在连接调用Receive方法时,会立即返回一个标记,告知用户程序内核缓存区有没有数据,如果有数据开始进行第二部分操作,从内核缓冲区拷贝到用户程序缓冲区。 由于系统会返回个标记,那可以通过轮询方式来判断内核缓冲区是否OK。

设置非阻塞模式参考代码:

SocketInformation sif=newSocketInformation();

sif.Options=SocketInformationOptions.NonBlocking;

sif.PRotocolInformation=newbyte[24];

Socket socket=newSocket(sif);

轮询参考代码:

while(true)

{byte[] msg =newbyte[256];vartemp =socket.Receive(msg);if(temp=="OK"){//do something}else{continue}

}

这种方式近乎淘汰了,了解即可。

基于回调的异步IO上面介绍过:

异步IO方式:连接Receive请求->立即返回->事件或回调通知当回调到执行时,数据已经在用户程序缓冲区已经准备好了,在回调代码中对这部分数据进行相应的逻辑即可。

发出接收请求:

staticbyte[] msg =newbyte[256];vartemp = socket.BeginReceive(msg,0, msg.Length,0,newAsyncCallback(ReadCallback), socket);

回调函数中对数据做处理:

publicstaticvoidReadCallback(IAsyncResult ar)

{varsocket =(Socket)ar.AsyncState;intread =socket.EndReceive(ar);

DoSomething(msg);

socket.BeginReceive(msg,0, msg.Length,0,newAsyncCallback(Read_Callback), socket);

}

当回调函数执行时,表示数据已经准备好,需要先结束接收请求EndReceive,以便第二次发出接收请求。 在服务端程序中要处理多个客户端的接收,再次发出BeginReceive接收数据请求即可。

这里的回调函数是在另外一个线程的触发,必要时要对数据加锁防止数据竞争:

Console.WriteLine(Thread.CurrentThread.ManagedThreadId);

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航