C#中的完成端口通信(一)
本人最近做的项目中涉及到网络通信,用到了完成端口,遂记录下来,供以后查阅,如果对您有点滴帮助之处,将不胜荣幸。话不多说,咋们直接进入主题吧。
一、传统Socket通信的弊端。回忆下,传统的网络通信是不是先创建一个Socket用于侦听,当客户端连接进来的时候就创建一个新的线程,接受连接,并启动一个新的Socket用于和客户端通信,对吧?也就是一个客户端对应一个线程。客户端少的时候倒没有什么,如果有10万个客户端进来呢?100万呢?1000万呢?光是线程切换就能把CPU累个半死!所以,传统网络通信的短板就出来了,那如何解决这个问题呢?其实微软的工程师早就注意到了该问题,他们重新设计了通信模式,将IO操作的发起与完成后的处理分开,让内核完成数据的IO操作,再用有限的几个用户线程做后续处理,从而避免过多的线程切换。
二、采用完成端口通信。采用完成端口通信时,操作系统会创建一个由内核管理的队列,你只需要将数据处理的线程注册到队列里面即可,当有数据到来时,由操作系统将数据先接收下来,然后内核调用你注册的处理程序(也就是你注册的线程)做后续处理。也就是说,当你收到操作系统的通知的时候,数据已经到内存中来了,所以你只需要关注如何做后续的处理。类似你去KFC点炸鸡:你点了炸鸡(创建任务)后,吧台会给你一个小票(绑定任务),然后你拿着小票就在旁边的候餐区等着(注册服务),KTV的工作人员帮你炸好后会通知你取走(收到通知,也说明数据也同步到了)!后面是吃也好,扔了也好,怎么处理炸鸡就是自己的事情了(用户线程的事情)。
三、在C#中使用完成端口通信。在C#中,微软通过SocketAsyncEventArgs类公布了完成端口的处理接口。所以只需要注册该类的完成操作的处理事件,然后在侦听Socket中把传入进来的链接与SocketAsyncEventArgs绑定即可。当然还有一些技术细节需要处理,如消息边界的处理,连接的检查等等。下一节我们来做个例子,来完成一个使用完成端口收发信息的Server端。

浙公网安备 33010602011771号