华为q2s-win7 activation v1 7
![socket error](/uploads/image/0402.jpg)
2023年4月3日发(作者:平板和笔记本区别)
Socket套接字连接状态判断,接收数据笔记
最近⼯作中涉汲到⼀些Socket⽅⾯应⽤,如断线重连,连接状态判断等,今天做了⼀些总结。
1.判断Socket连接状态
通过Poll与Connected结合使⽤,重点关注SelectRead模式
⽅法名:
(intmicroSeconds,Modemode)⽅法参数:
参数枚举:
SelectRead如果已调⽤Listen(Int32)并且有挂起的连接,则为true。-或-如果有数据可供读取,则为true。-或-如果连接已关闭、重置
或终⽌,则返回true;否则,返回false。
SelectWrite如果正在处理Connect(EndPoint)并且连接已成功,则为true;-或-如果可以发送数据,则返回true;否则,返回false。
SelectError如果正在处理不阻⽌的Connect(EndPoint),并且连接已失败,则为true;-或-如果OutOfBandInline未设置,并且带外数据
可⽤,则为true;否则,返回false。
SelectRead模式返回true的三种情况,若Socket处挂起状态,同时没有数据可读取,可以确定Socket是关闭或终⽌的。
1.已调⽤Listen(Int32)并且有挂起的连接,则为true
2.有数据可供读取,则为true
3.如果连接已关闭、重置或终⽌,则返回true
如下代码,true表⽰连接断开
(1000,Read)&&(ble==0)||!ted
稍作调整,判断连接状态完整代码如下:
publicstaticboolIsSocketConnected(Sockets)
{
#regionremarks
/*Aszendarwrote,ble,butyouneedtotakeintoconsideration
*thatthesocketmightnothavebeeninitializedinthefirstplace.
*Thisisthelast(Ibelieve)tedproperty.
*Therevisedversionofthemethodwouldlookssomethinglikethis:
*from:/questions/2661764/how-to-check-if-a-socket-is-connected-disconnected-in-c*/
#endregion
#region过程
if(s==null)
returnfalse;
return!(((1000,Read)&&(ble==0))||!ted);
/*Thelong,butsimpler-to-understandversion:
boolpart1=(1000,Read);
boolpart2=(ble==0);
if((part1&&part2)||!ted)
returnfalse;
else
returntrue;
*/
#endregion
}
Blocking属性
默认情况Blocking为true,即阻塞状态,Read时若没收到数据,Socket会挂起当前线程,直到收到数据,当前线程才被唤醒。适⽤于接收
到数据完成后再进⾏下⼀步操作场景。反之Blocking为false,调⽤Recevied后,⽆论是否收到数据,都⽴即返回结果,当前线程可以继
续执⾏。
MSDN强调,Blocking属性值与异步操作如(Begin开始API)BeginReceive等没有相关性,⽐如通过BeginReceive接收数据,同时希望
当前线程挂起,看起来,似乎可将Blocking设为true实现。其实不然,需要通过信号量ManualResetEvent实现挂起操作。
resendingandreceivingdataasynchronouslyandwanttoblockexecution,
usetheclass
发送数据时,⾃动断线重连
如添加⼼跳机制。这⾥另⼀个简单⽅案,在发送数据时,检查连接状态,如发现断开,重新建⽴连接,这⾥Socket操作加了锁,防⽌并发
操作。
publicstaticboolSendServer(stringst)//发送
{
lock(SocketLock)
{
try
{
if(SocketClient==null||!ted){
//断开连接
if(SocketClient!=null)
CloseSocket(SocketClient);
//重新连接
if(!onnect(,)){
returnfalse;
}
}
tchwatch=tch();
();
byte[]Msg=es(st);
(Msg);
//接收相机返回结果
byte[]bytResult;
Receive(SocketClient,socketBuffer,0,EndMathFormat,eTimeout,outbytResult);
();
("获取相机坐标信息耗时(ms):"+dMilliseconds);
stringReciveMsg=ing(bytResult).TrimEnd(newchar[]{'n','0'});
Msg=ReciveMsg;
=ReciveMsg;
ew((s)=>{MyEvent(ng());},ReciveMsg);
returntrue;
}
catch(Exceptionex)
{
(ex,"发送消息给相机⽤来切换功能异常");
if(!IsSocketConnected(SocketClient))
{
//断开连接
CloseSocket(SocketClient);
//重新连接
onnect(,);
}
}
returnfalse;
}
}
接收数据场景
通常两种场景,如:
a.接收指定长度数据包。
b.接收不定长数据包,根据终⽌符结束。(不定长数据包以末尾n0做为结束标记,本⽰例可能返回包含多条终⽌符数据,需对结果⼆
次分隔,如abcn0defn0)
=>定长数据包接收:
///
///socket接收定长数据
///
///
///
///
///
///
publicstaticvoidReceive(Socketsocket,byte[]buffer,intoffset,intsize,inttimeout)
{
intendTickCount=unt+timeout;
intreceived=0;//howmanybytesisalreadyreceived
interrTimes=0;
do
{
if(unt>endTickCount)
thrownewException("ReceiveTimeout.");
try
{
received+=e(buffer,offset+received,size-received,);
}
catch(SocketExceptionex)
{
if(ErrorCode==lock||
ErrorCode==ing||
ErrorCode==erSpaceAvailable)
{
if(++errTimes>3)
thrownewException("ReceiveerrTimes引发异常");
//socketbufferisprobablyempty,waitandtryagain
(30);
}
else
throwex;//anyseriouserroroccurr
}
}while(received
}
=>不定长数据包接收:
publicstaticvoidReceive(Socketsocket,byte[]buffer,intoffset,byte[]endMath,inttimeout,outbyte[]bytResult)
{
intendTickCount=unt+timeout;
intreceived=0;//howmanybytesisalreadyreceived
intsize=;
boolisMatch=false;
interrTimes=0;
intj=0;
do
{
if(unt>endTickCount)
thrownewException("ReceiveTimeout.");
try
{
received+=e(buffer,offset+received,size-received,);
isMatch=true;
j=0;
for(inti=;i
{
if(buffer[i]!=endMath[j++])
{
isMatch=false;
break;
}
}
if(isMatch)
{
break;
}
if(received>=size)
{
thrownewException("Receive结束符⾮预期!");
}
}
catch(SocketExceptionex)
{
if(ErrorCode==lock||
ErrorCode==ing||
ErrorCode==erSpaceAvailable)
{
if(++errTimes>3)
thrownewException("ReceiveerrTimes引发异常");
//socketbufferisprobablyempty,waitandtryagain
(30);
}
else
throwex;//anyseriouserroroccurr
}
}while(true);
bytResult=newbyte[received];
(buffer,0,bytResult,0,received);
}
5.关闭Socket
privatestaticvoidCloseSocket(Socketsocket)
{
try
{
if(socket!=null)
{
wn();
();
}
}
catch(Exceptionex)
{
(ex,"关闭socket时发⽣异常:"+e);
}
finally{
socket=null;
}
}
更多推荐
socket error
发布评论