一个封装的异步Socket客户端


项目需要封装一个异步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


#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、正则应用之——日期正则表达式 (转)


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号