微信号:gh_98bfb3afe7eb

介绍:.net .net跳槽 c#跳槽 C#程序员 .net软件工程师 SQL Server 等等,本公众号为求职、发布求职信息、以及.net等相关技术的交流平台.

.NET Socket开发之异步Socket

2017-08-05 23:26 DotNet开发跳槽

在基于.NET的网络服务端的开发中,我们用到和听到的最多的恐怕就是异步Socket了。异步Socket的性能比同步高出很多,但是编写代码比较复杂。因此异步Socket也是网络上讨论比较多的话题。

今天,我们就来讨论一下如何用异步Socket开发网络应用。在此之前我们先讨论两个问题。

一、异步Socket是如何工作的:

那异步Socket是如何工作的呢?我以接收一条消息来说明这个问题。首先,程序向系统投递一个接收数据的请求,并为其指定一个数据缓冲区和回调函数,回调函数用来指示当数据到达后将如何处理,然后我们的程序继续执行下去,当有数据到达的时候,系统将数据读入缓冲区,并执行回调函数,处理这条消息。我们并不需要关心这条消息何时到达。

二、什么情况下我们用异步Socket

有些人认为,异步Socket的性能比同步Socket的性能高很多,应该在各种环境下都用异步Socket,其实不然。在某些环境下面。异步反到比同步的性能低,那么在哪些情况下会这样呢?

1、 客户端Socket

2、 服务端连接数比较少。

3、 连接数很多,但都是短连接。

在这些环境下,我们用同步Socket不但可以简化代码,而且性能并不会比异步Socket低。但在服务端连接比较多而且是长连接的情况下,我们就要使用异步Socket

现在我们来看看如何用异步Socket编程。

首先,我们要建立一个Socket用来监听:


            Socket _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint localEP 
= new IPEndPoint(_address, _port);
            _listener.Bind(localEP);
            _listener.Listen(
100);

然后创建一个线程来处理客户端连接请求:


            Thread _acceptWorkThread = new Thread(AcceptWorkThread);
            _acceptWorkThread.Start();

        
private void AcceptWorkThread()
        
{
            
while (_isListener)
            
{
                UserInfo info 
= new UserInfo();//这个UserInfo是用来保存客户信息的。
                info.socket = socket;
                Socket socket 
= _listener.Accept();
                
//这里进行其它处理。
                socket.BeginReceive(info.Buffer, 0, info.Buffer.Length, SocketFlags.None, ReceiveCallBack, info);//这里向系统投递一个接收信息的请求,并为其指定ReceiveCallBack做为回调函数
            }

        }
 我们再来看看回调函数的定义:
        private void ReceiveCallBack(IAsyncResult ar)
        
{
            UserInfo info 
= (UserInfo)ar.AsyncState;
            Socket handler 
= info.socket;
            
int readCount = 0;
            
try
            
{
                readCount 
= handler.EndReceive(ar);//调用这个函数来结束本次接收并返回接收到的数据长度。
            }

            
catch (SocketException)//出现Socket异常就关闭连接
            {
                CloseSocket(info);
//这个函数用来关闭客户端连接
                return;
            }

            
catch
            
{
            }

            
if (readCount > 0)
            
{
                
byte[] buffer = new byte[readCount];
                Buffer.BlockCopy(info.Buffer, 
0, buffer, 0, readCount);
                Analyzer(info, buffer);
//这个函数用来处理接收到的信息。
                try
                
{
                    handler.BeginReceive(info.Buffer, 
0, info.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), info);//向系统投递下一个接收请求
                }

                
catch (SocketException) //出现Socket异常就关闭连接
                {
                    CloseSocket(info);
                }

                
catch
                
{
                }

            }

            
else //如果接收到0字节的数据说明客户端关闭了Socket,那我们也要关闭Socket
            {
                CloseSocket(info);
            }

        }

接下来我们看看如何发送数据给客户端:


        public void Send(Socket socket, byte message)
        
{
            
try
            
{
                info.socket.BeginSend(message, 
0, _byte.Length, SocketFlags.None, new AsyncCallback(SendCallBack), info);//这里向系统投递一个发送数据的请求,并指定一个回调函数。
            }

            
catch (SocketException ex)
            
{
                CloseSocket(info);
            }

            
catch
            
{
            }

        }

定义发送回调函数:


        private void SendCallBack(IAsyncResult ar)
        
{
            UserInfo info 
= (UserInfo)ar.AsyncState;
            
try
            
{
                info.socket.EndSend(ar);
//调用这个函数来结束本次发送。
            }

            
catch
            
{
            }

        }

 

好了,整个监听、接收、发送的过程就完成了,很简单吧。现在需要说明的是,我在这里接收客户端连接的Accept是用的同步的,我个人认为在这里用同步的会比用异步好一些。因为这样代码简单而且没有性能上的损失。


来源:http://www.cnblogs.com/wzd24/archive/2007/06/15/782833.html

图书推荐:

简介:《高效程序员的45个习惯:敏捷开发修炼之道(修订版)》总结并生动地阐述了成为高效的开发人员所需具备的45个习惯、思想观念和方法,涵盖了软件开发进程、编程和调试工作、开发者态度、项目和团队管理以及持续学习等几方面。

购买方式:

淘短链接 淘口令(30天内有效)
https://s.click.taobao.com/qW3ROfw  ¥tAsn008R6G0¥

点击上面链接再选择浏览器打开,或者复制淘口令在淘宝客户端打开

《代码整洁之道 Clean Code》包邮,并送2元优惠卷

 

正版代码整洁之道Clean Code 整洁代码的敏捷实践方法代码阅读当今权威代码大全计算机语言程序设计经典书

优惠购买方式:点击链接再选择浏览器打开https://s.click.taobao.com/5TlXCiw转到商品链接

,领取优惠券地址:https://s.click.taobao.com/wfgXCiw,或复制这条信息¥Bp26ZxeZTqv¥后打开手机淘宝,手机淘宝领取优惠券¥ZubdZxeZ5qc


 
DotNet开发跳槽 更多文章 30 岁之前,应当学会哪些技能? 这个时代,很多人都会焦虑,但焦虑是最无用的情感 苦恼找不到工作激情?你最好赶快做这三件事 一位程序员工作10年总结了这些忠告 优秀的程序员10分钟内能搞定下面5个编程问题,你呢?
猜您喜欢 【开源】分布式机器学习工具包 Go语言并发模型:使用 select UI设计如何零配色,无参考创建安全配色方案 花川学院 Swift2 端午节大餐 来袭! 今日头条:架构师不写代码能知道技术的痛点?