
Code
void OnReceiveCompleted(object sender,SocketAsyncEventArgs e){}
SocketAsyncEventArgs receive=new SocketAnyncEventArgs();
receive.Completed+= OnReceiveCompleted;
receive.SetBuffer(buffer,0,buffer.Length);
socket.ReceiveAsync(receive);
在这里我们可以看出3.5 和 2.0 的一个明显区别,那就是不是使用IAsyncResult而是用SocketAsyncEventArgs作为上下文对象。应用程序创建并管理(并且可以重复使用)SocketAsyncEventArgs 对象。套接字操作的所有参数都由 SocketAsyncEventArgs 对象的属性和方法指定。完成状态也由 SocketAsyncEventArgs 对象的属性提供。最后,需要使用事件处理程序回调完成方法。
让我们来看看代码:
首先我们创建一个用户类,用来存储和客户端有关的数据:

Code
public class UserObject

{

/**//// <summary>
/// 接收数据的缓冲区
/// </summary>

public byte[] ReceiveBuffer
{ get; private set; }

/**//// <summary>
/// 发送数据的缓冲区
/// </summary>

public byte[] SendBuffer
{ get; private set; }

/**//// <summary>
/// 客户端Socket对象
/// </summary>

public Socket Socket
{ get; private set; }

/**//// <summary>
/// 发送数据上下文对象
/// </summary>

public SocketAsyncEventArgs SendEventArgs
{ get; private set; }

/**//// <summary>
/// 接收数据上下文对象
/// </summary>

public SocketAsyncEventArgs ReceiveEventArgs
{ get; private set; }

public UserObject(Socket socket)

{
ReceiveBuffer = new byte[1024];//定义接收缓冲区
SendBuffer = new byte[1024];//定义发送缓冲区
this.Socket = socket;
SendEventArgs = new SocketAsyncEventArgs();
SendEventArgs.UserToken = this;
ReceiveEventArgs = new SocketAsyncEventArgs();
ReceiveEventArgs.UserToken = this;
ReceiveEventArgs.SetBuffer(ReceiveBuffer, 0, ReceiveBuffer.Length);//设置接收缓冲区
SendEventArgs.SetBuffer(SendBuffer, 0, SendBuffer.Length);//设置发送缓冲区
}
}接下来我们开始接入客户端连接:

Code
1
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
2
socket.Bind(localEP);
3
socket.Listen(100);
4
Console.WriteLine("Server is bind on {0}",socket.LocalEndPoint);
5
acceptEventArgs = new SocketAsyncEventArgs();//创建接入Socket上下文对象
6
acceptEventArgs.Completed += acceptCompleted;//注册接入完成事件处理程序
7
socket.AcceptAsync(acceptEventArgs);//投递接入操作
8
Console.WriteLine("Server is started");
9
10
//接入事件处理程序
11
void acceptCompleted(object sender, SocketAsyncEventArgs e)
12

{
13
var client = new UserObject( e.AcceptSocket);//创建用户对象实例
14
client.ReceiveEventArgs.Completed += Receives_Completed;//注册接收数据完成事件处理程序
15
client.SendEventArgs.Completed += Send_Completed;//注册发送数据完成事件处理程序
16
client.Socket.ReceiveAsync(client.ReceiveEventArgs);//投递接收数据操作
17
}
好了,我们开始接收数据:

Code
1
//接收数据完成事件处理程序
2
void Receives_Completed(object sender, SocketAsyncEventArgs e)
3

{
4
var client = e.UserToken as UserObject;
5
if (e.BytesTransferred == 0)//如果传输的数据量为0,则表示链接已经断开
6
{
7
Console.WriteLine("Socket:{0} is closed",client.Socket.Handle);
8
client.Socket.Close();
9
}
10
else
11
{
12
string message = Encoding.Unicode.GetString(e.Buffer, 0, e.BytesTransferred);//获取接收到的数据
13
Console.WriteLine("Socket:{0} send message:{1}",client.Socket.Handle,message);
14
string sent=string.Format("{0} bytes has been received",e.BytesTransferred);
15
int length = Encoding.Unicode.GetBytes(sent,0,sent.Length,client.SendBuffer,0);//将数据写入发送缓冲区
16
client.SendEventArgs.SetBuffer(0, length);//设置缓冲区中有效数据的偏移量和长度
17
client.Socket.SendAsync(client.SendEventArgs);//投递发送数据操作
18
client.Socket.ReceiveAsync(client.ReceiveEventArgs);//投递接收数据操作
19
}
20
}
21
22
//发送数据完成事件处理程序
23
void Send_Completed(object sender, SocketAsyncEventArgs e)
24

{
25
var client = e.UserToken as UserObject;
26
if (e.BytesTransferred==0)//如果传输的数据量为0,则表示链接已经断开
27
{
28
Console.WriteLine("Socket:{0} is closed", client.Socket.Handle);
29
client.Socket.Close();
30
}
31
else
32
精彩图集