项目需要封装一个异步Socket客户端,现将代码写下来,请各位指点一下:
usingSystem;
usingSystem.Collections;
usingSystem.Configuration;
usingSystem.Net;
usingSystem.Net.Sockets;
usingSystem.Text;
namespaceBeijing.Traffic.Mobile.Net
{
/**////<summary>
///智能手机端网络访问类
///</summary>
publicclassMobileClient
{
//服务器IP地址
privatestringserverIP;
//服务器访问端口
privatestringserverPort;
privateSocketsocket;
privatebyte[]buffer=newbyte[256];
privateStringBuilderreceiveData=null;
privateSocketEventArgssocketEventArgs=null;
事件#region事件
//连接完成事件
publiceventEventHandlerOnConnect;
//接收完成事件
publiceventEventHandlerOnReceivedFinshed;
//发送数据成功
publiceventEventHandlerOnSendFinished;
//产生异常时调用此事件
publiceventEventHandlerOnException;
#endregion
构造函数#region构造函数
publicMobileClient()
{
this.serverIP=ConfigurationSettings.AppSettings["ServerIP"];
this.serverPort=ConfigurationSettings.AppSettings["ServerPort"];
receiveData=newStringBuilder();
}
publicMobileClient(stringip,stringport)
{
this.serverIP=ip;
this.serverPort=port;
receiveData=newStringBuilder();
}
#endregion
privatevoidUpdateEventMessage(stringmsg)
{
if(socketEventArgs==null)
{
socketEventArgs=newSocketEventArgs();
socketEventArgs.ServerIP=this.serverIP;
socketEventArgs.ServerPort=this.serverPort;
}
socketEventArgs.Message=msg;
}
/**////<summary>
///处理异常的事件
///</summary>
///<paramname="msg"></param>
privatevoidHandlerException(stringmsg)
{
if(OnException!=null)
{
UpdateEventMessage(msg);
OnException(this,socketEventArgs);
}
else
{
thrownewException("异常处理事件不能为空");
}
}
连接远程服务器#region连接远程服务器
/**////<summary>
///异步连接远程服务器
///</summary>
///<returns></returns>
publicvoidConnect()
{
try
{
if(socket!=null&&socket.Connected)
{
socket.Shutdown(SocketShutdown.Both);
System.Threading.Thread.Sleep(10);
socket.Close();
}
socket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
IPEndPointepServer=newIPEndPoint(IPAddress.Parse(serverIP),int.Parse(serverPort));
socket.Blocking=false;
socket.BeginConnect(epServer,newAsyncCallback(Connected),socket);
}
catch(Exceptionex)
{
this.Close();
this.HandlerException(ex.Message);
}
}
privatevoidConnected(IAsyncResultar)
{
try
{
Socketsock=(Socket)ar.AsyncState;
if(sock.Connected)
{
if(OnConnect!=null)
{
//连接成功事件
UpdateEventMessage("连接远程服务器成功");
OnConnect(this,socketEventArgs);
}
}
else
{
//连接失败事件
this.HandlerException("连接远程服务器失败");
}
}
catch(Exceptionex)
{
this.Close();
this.HandlerException(ex.Message);
}
}
#endregion
异步发送数据#region异步发送数据
publicvoidSend(stringmsg)
{
byte[]msgBytes=Encoding.ASCII.GetBytes(msg);
Send(msgBytes);
}
publicvoidSend(byte[]msgBytes)
{
try
{
if(this.socket==null||!this.socket.Connected)
{
thrownewException("远程服务器没有连接,请先连接");
}
else
{
AsyncCallbacksendData=newAsyncCallback(SendCallback);
this.socket.BeginSend(msgBytes,0,msgBytes.Length,SocketFlags.None,sendData,socket);
}
}
catch(Exceptionex)
{
this.Close();
this.HandlerException(ex.Message);
}
}
privatevoidSendCallback(IAsyncResultar)
{
try
{
Socketclient=(Socket)ar.AsyncState;
intbytesSent=client.EndSend(ar);
if(bytesSent>0)
{
if(this.OnSendFinished!=null)
{
UpdateEventMessage("发送数据成功");
OnSendFinished(this,socketEventArgs);
}
}
else
{
this.HandlerException("发送数据失败");
}
}
catch(Exceptionex)
{
this.Close();
this.HandlerException(ex.Message);
}
}
#endregion
异步接受数据#region异步接受数据
publicvoidReceive()
{
try
{
if(this.socket==null||!this.socket.Connected)
{
thrownewException("远程服务器没有连接,请先连接");
}
else
{
AsyncCallbackrecieveData=newAsyncCallback(OnReceiveData);
socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,recieveData,socket);
}
}
catch(Exceptionex)
{
this.Close();
this.HandlerException(ex.Message);
}
}
privatevoidOnReceiveData(IAsyncResultar)
{
Socketsock=(Socket)ar.AsyncState;
try
{
intnBytesRec=sock.EndReceive(ar);
if(nBytesRec>0)
{
//接受数据并保存
stringsRecieved=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(Exceptionex)
{
this.Close();
this.HandlerException(ex.Message);
}
}
#endregion
接收到的数据#region接收到的数据
/**////<summary>
///接收到的数据
///</summary>
publicstringReceivedData
{
get
{
lock(this)
{
returnthis.receiveData.ToString();
}
}
}
#endregion
关闭socket#region关闭socket
publicvoidClose()
{
try
{
if(socket!=null&&socket.Connected)
{
socket.Shutdown(SocketShutdown.Both);
System.Threading.Thread.Sleep(10);
socket.Close();
}
}
catch(Exceptionex)
{
this.HandlerException(ex.Message);
}
}
#endregion
}
}
业务类在对此包装的socket进行访问时,由于是三个线程之间进行通讯,这个线程无法捕捉另一个线程产生的异常,所以通过信号量来通知是否有异常的产生:
#defineTEST
usingSystem;
usingSystem.Threading;
usingSystem.Text;
usingBeijing.Traffic.Mobile.Net;
namespaceBeijing.Traffic.Mobile.Bussiness
{
/**////<summary>
///业务逻辑的基类。
///</summary>
publicabstractclassBussinessBase
{
#ifTEST
//手机Socket客户端
publicMobileClientmobileClient=null;
#else
protectedMobileClientmobileClient=null;
#endif
protectedbyte[]receicedBytes=null;
//是否产生了Socket异常
privateboolhasException=false;
//异常消息类
privateExceptionsocketException=null;
//三个线程通知事件
protectedManualResetEventconnectDone=newManualResetEvent(false);
protectedManualResetEventsendDone=newManualResetEvent(false);
protectedManualResetEventreceiveDone=newManualResetEvent(false);
publicBussinessBase()
{
}
/**////<summary>
///获取手机网络连接客户端类
///</summary>
///<returns></returns>
publicMobileClientGetMobileClient()
{
if(mobileClient==null)
{
mobileClient=newMobileClient("210.73.74.200","3333");
mobileClient.OnConnect+=newEventHandler(mobileClient_OnConnect);
mobileClient.OnSendFinished+=newEventHandler(mobileClient_OnSendFinished);
mobileClient.OnReceivedFinshed+=newEventHandler(mobileClient_OnReceivedFinshed);
mobileClient.OnException+=newEventHandler(mobileClient_OnException);
}
returnmobileClient;
}
事件#region事件
protectedvoidmobileClient_OnConnect(objectsender,System.EventArgse)
{
this.connectDone.Set();
}
protectedvoidmobileClient_OnException(objectsender,System.EventArgse)
{
SocketEventArgssocketEventArgs=easSocketEventArgs;
ChangeExceptionStatus(true);
UpdateExceptionMessage(socketEventArgs.Message);
this.connectDone.Set();
}
protectedvoidmobileClient_OnSendFinished(objectsender,System.EventArgse)
{
ChangeExceptionStatus(false);
this.sendDone.Set();
}
protectedvoidmobileClient_OnReceivedFinshed(objectsender,System.EventArgse)
{
ChangeExceptionStatus(false);
this.receiveDone.Set();
}
#endregion
处理异常#region处理异常
/**////<summary>
///改变异常信号量
///</summary>
///<paramname="hasException"></param>
privatevoidChangeExceptionStatus(boolhasException)
{
lock(this)
{
this.hasException=hasException;
}
}
/**////<summary>
///生成异常类
///</summary>
///<paramname="msg"></param>
privatevoidUpdateExceptionMessage(stringmsg)
{
socketException=newException(msg);
}
/**////<summary>
///判断是否产生了异常
///</summary>
privatevoidHasException()
{
lock(this)
{
if(hasException==true)
{
throwsocketException;
}
}
}
#endregion
业务#region业务
/**////<summary>
///作一次业务请求
///</summary>
///<paramname="package"></param>
protectedvoidBusinessRequet(byte[]package)
{
MobileClientmobileClient=this.GetMobileClient();
mobileClient.Connect();
this.connectDone.WaitOne();
HasException();
mobileClient.Send(package);
this.sendDone.WaitOne();
HasException();
mobileClient.Receive();
this.receiveDone.WaitOne();
HasException();
receicedBytes=Encoding.ASCII.GetBytes(mobileClient.ReceivedData);
mobileClient.Close();
}
}
优质内容筛选与推荐>>
1、Linux Java 环境变量设置2、异步、同步委托解析(一)3、验证4、Android基础之广播5、正则应用之——日期正则表达式 (转)