项目需要封装一个异步Socket客户端,现将代码写下来,请各位指点一下 :
using System;
using System.Collections;
using System.Configuration;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Beijing.Traffic.Mobile.Net
{
/// <summary>
/// 智能手机端网络访问类
/// </summary>
public class MobileClient
{
//服务器IP地址
private string serverIP;
//服务器访问端口
private string serverPort;
private Socket socket;
private byte [] buffer = new byte[256];
private StringBuilder receiveData = null;
private SocketEventArgs socketEventArgs = null; 
#region 事件
//连接完成事件
public event EventHandler OnConnect;
//接收完成事件
public event EventHandler OnReceivedFinshed;
//发送数据成功
public event EventHandler OnSendFinished;
//产生异常时调用此事件
public event EventHandler OnException;
#endregion 
#region 构造函数
public MobileClient()
{
this.serverIP = ConfigurationSettings.AppSettings["ServerIP"];
this.serverPort = ConfigurationSettings.AppSettings["ServerPort"];
receiveData = new StringBuilder();
}
public MobileClient(string ip,string port)
{
this.serverIP = ip;
this.serverPort = port;
receiveData = new StringBuilder();
}
#endregion 
private void UpdateEventMessage(string msg)
{
if( socketEventArgs == null)
{
socketEventArgs = new SocketEventArgs();
socketEventArgs.ServerIP = this.serverIP;
socketEventArgs.ServerPort = this.serverPort;
}
socketEventArgs.Message = msg;
}
/// <summary>
/// 处理异常的事件
/// </summary>
/// <param name="msg"></param>
private void HandlerException(string msg)
{
if(OnException != null)
{
UpdateEventMessage(msg);
OnException(this,socketEventArgs);
}
else
{
throw new Exception("异常处理事件不能为空");
}
}
#region 连接远程服务器

/// <summary>
/// 异步连接远程服务器
/// </summary>
/// <returns></returns>
public void Connect()
{
try
{
if( socket != null && socket.Connected )
{
socket.Shutdown( SocketShutdown.Both );
System.Threading.Thread.Sleep( 10 );
socket.Close();
}
socket = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); 
IPEndPoint epServer = new IPEndPoint(IPAddress.Parse(serverIP),int.Parse(serverPort));
socket.Blocking = false;
socket.BeginConnect( epServer, new AsyncCallback(Connected),socket );
}
catch(Exception ex)
{
this.Close();
this.HandlerException(ex.Message);
}
}
private void Connected( IAsyncResult ar )
{
try
{
Socket sock = (Socket)ar.AsyncState;
if( sock.Connected )
{
if(OnConnect != null)
{
//连接成功事件
UpdateEventMessage("连接远程服务器成功");
OnConnect(this,socketEventArgs);
}
}
else
{
//连接失败事件
this.HandlerException("连接远程服务器失败");
}
}
catch(Exception ex)
{
this.Close();
this.HandlerException(ex.Message);
}
}
#endregion
#region 异步发送数据
public void Send(string msg)
{
byte[] msgBytes = Encoding.ASCII.GetBytes(msg);
Send(msgBytes);
}
public void Send(byte [] msgBytes)
{
try
{
if( this.socket == null || !this.socket.Connected )
{
throw new Exception("远程服务器没有连接,请先连接");
}
else
{
AsyncCallback sendData = new AsyncCallback(SendCallback);
this.socket.BeginSend(msgBytes,0,msgBytes.Length,SocketFlags.None,sendData,socket);
}
}
catch(Exception ex)
{
this.Close();
this.HandlerException(ex.Message);
}
}

private void SendCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket) ar.AsyncState;
int bytesSent = client.EndSend(ar);
if( bytesSent > 0)
{
if( this.OnSendFinished != null)
{
UpdateEventMessage("发送数据成功");
OnSendFinished(this,socketEventArgs);
}
}
else
{
this.HandlerException("发送数据失败");
}
}
catch (Exception ex)
{
this.Close();
this.HandlerException(ex.Message);
}
}

#endregion
#region 异步接受数据
public void Receive()
{
try
{
if( this.socket == null || !this.socket.Connected )
{
throw new Exception("远程服务器没有连接,请先连接");
}
else
{
AsyncCallback recieveData = new AsyncCallback( OnReceiveData );
socket.BeginReceive( buffer, 0, buffer.Length, SocketFlags.None, recieveData, socket );
}
}
catch( Exception ex )
{
this.Close();
this.HandlerException(ex.Message);
}
}

private void OnReceiveData(IAsyncResult ar)
{
Socket sock = (Socket)ar.AsyncState;
try
{
int nBytesRec = sock.EndReceive( ar );
if( nBytesRec > 0 )
{
//接受数据并保存
string sRecieved = Encoding.ASCII.GetString(buffer, 0, nBytesRec );
receiveData.Append(sRecieved);
Receive();
}
else
{
sock.Shutdown( SocketShutdown.Both );
sock.Close();
if(receiveData.Length != 0)
{
if(OnReceivedFinshed != null)
{
UpdateEventMessage("接受数据成功");
OnReceivedFinshed(this,socketEventArgs);
}
}
else
{
this.HandlerException("接受数据为空");
}
}
}
catch( Exception ex )
{
this.Close();
this.HandlerException(ex.Message);
}
}

#endregion
#region 接收到的数据
/// <summary>
/// 接收到的数据
/// </summary>
public string ReceivedData
{
get
{
lock(this)
{
return this.receiveData.ToString();
}
}
}
#endregion
#region 关闭socket
public void Close()
{
try
{
if( socket != null && socket.Connected )
{
socket.Shutdown( SocketShutdown.Both );
System.Threading.Thread.Sleep( 10 );
socket.Close();
}
}
catch(Exception ex)
{
this.HandlerException(ex.Message);
}
}
#endregion

}
}
业务类在对此包装的socket进行访问时,由于是三个线程之间进行通讯,这个线程无法捕捉另一个线程产生的异常,所以通过信号量来通知是否有异常的产生:













