Socket同步与同步比较 c#网络编程

      今天,大家就来讨论一下如何用异步Socket开发网络应用。在此之前大家先讨论两个问题。在基于c#的网络server端的开发中,大家用到和听到的最多的恐怕就是异步Socket了。异步Socket的性能比同步高出很多,但是编写代码比较复杂。因此异步Socket也是网络上讨论比较多的话题。

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

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

二、什么情况下大家用异步Socket:

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

1、client端Socket。

2、 server端连接数比较少。

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

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

      现在大家来看看如何用异步Socket编程。

首先,大家要建立一个Socket用来监听:

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

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

 1 Thread _acceptWorkThread = new Thread(AcceptWorkThread); 
 2 _acceptWorkThread.Start(); 
 3 
 4 private void AcceptWorkThread() 
 5 { 
 6 while (_isListener) 
 7 { 
 8 UserInfo info = new UserInfo();//这个UserInfo是用来保存客户信息的。 
 9 info.socket = socket; 
10 Socket socket = _listener.Accept(); 
11 //这里进行其它处理。 
12 socket.BeginReceive(info.Buffer, 0, info.Buffer.Length, SocketFlags.None, ReceiveCallBack, info);//这里向系统投递一个接收信息的请求,并为其指定ReceiveCallBack做为回调函数 
13 } 
14 } 我们再来看看回调函数的定义: 
15 private void ReceiveCallBack(IAsyncResult ar) 
16 { 
17 UserInfo info = (UserInfo)ar.AsyncState; 
18 Socket handler = info.socket; 
19 int readCount = 0; 
20 try 
21 { 
22 readCount = handler.EndReceive(ar);//调用这个函数来结束本次接收并返回接收到的数据长度。 
23 } 
24 catch (SocketException)//出现Socket异常就关闭连接 
25 { 
26 CloseSocket(info);//这个函数用来关闭客户端连接 
27 return; 
28 } 
29 catch 
30 { 
31 } 
32 if (readCount > 0) 
33 { 
34 byte[] buffer = new byte[readCount]; 
35 Buffer.BlockCopy(info.Buffer, 0, buffer, 0, readCount); 
36 Analyzer(info, buffer);//这个函数用来处理接收到的信息。 
37 try 
38 { 
39 handler.BeginReceive(info.Buffer, 0, info.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), info);//向系统投递下一个接收请求 
40 } 
41 catch (SocketException) //出现Socket异常就关闭连接 
42 { 
43 CloseSocket(info); 
44 } 
45 catch 
46 { 
47 } 
48 } 
49 else //如果接收到0字节的数据说明客户端关闭了Socket,那我们也要关闭Socket 
50 { 
51 CloseSocket(info); 
52 } 
53 }

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

 1 public void Send(Socket socket, byte message) 
 2 { 
 3 try 
 4 { 
 5 info.socket.BeginSend(message, 0, _byte.Length, SocketFlags.None, new AsyncCallback(SendCallBack), info);//这里向系统投递一个发送数据的请求,并指定一个回调函数。 
 6 } 
 7 catch (SocketException ex) 
 8 { 
 9 CloseSocket(info); 
10 } 
11 catch 
12 { 
13 } 
14 }

定义发送回调函数:

 1 private void SendCallBack(IAsyncResult ar) 
 2 { 
 3 UserInfo info = (UserInfo)ar.AsyncState; 
 4 try 
 5 { 
 6 info.socket.EndSend(ar);//调用这个函数来结束本次发送。 
 7 } 
 8 catch 
 9 { 
10 } 
11 }

      好了,整个监听、接收、发送的过程就完成了,很简单吧,其实就是这么简单,多动动手就OK。现在需要说明的是,我在这里接收客户端连接的Accept是用的同步的,我个人认为在这里用同步的会比用异步好一些。因为这样代码简单而且没有性能上的损失。好了本文到此结束,更多请敬请期待:http://www.bjp111.com

转载于:https://www.cnblogs.com/leyoutt/archive/2013/04/25/3042587.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值