您的位置:首页 > 编程语言 > C#

[C#]关于事件驱动的SOCKET类的优化

2009-08-22 08:50 274 查看
在上一篇《[C#]事件驱动的SOCKET类》的文章中,地址:http://blog.csdn.net/much0726/archive/2009/06/25/4296789.aspx,我简单写了一个客户端的SOCKET连接类,并将接收的数据通知到SOCKET事件和数据包事件中,由于本人经验的不足,在数据判断上出现一些问题,原来写的文章中,我也会注明下本篇对其进行的进一步修改:

不能将socket.Poll(-1, SelectMode.SelectRead)方法作为判断SOCKET是否可以读的标准,此方法不能检测某些类型的连接问题,例如,网络电缆中断或远程主机意外关闭。您必须尝试发送或接收数据以检测这些类型的错误。在CSDN的论坛上也有人指出这个问题了,并且在微软的MSDN上也有权威的解释:http://technet.microsoft.com/zh-cn/system.net.sockets.socket.poll.aspx.

我原来的代码在服务器上运行一段时间后(大概1天左右),会出现接收不到SOCKET数据的情况,我就在判断前后加上了日志跟踪,果然是这个方法判断上出了问题。在C#写的接收数据方法上并不需要多余的判断,只要直接使用socket.Receive()即可,如果接收的字节数为0或者抛出SocketException异常,就可以判断网络连接是否断开了。下面是修改后的代码:

//接收线程
public void Thread_Read()
{
while (true)
{
try
{
//使用数据缓冲
byte[] DataBuffer = new byte[DataBufferSize - DataBufferSizeLast];
int receivedBytesCount = socket.Receive(DataBuffer, DataBufferSize -

DataBufferSizeLast, SocketFlags.None);

if (receivedBytesCount == 0)
{
//socket连接已断开
Socket_e.ResCode = "00000";
SocketEvent(this, Socket_e);
return;
}

int iTempDataBufferSizeLast = 0;
byte[] TempBytes = new byte[receivedBytesCount + DataBufferSizeLast];

//receivedBytesCount + DataBufferSizeLast

if (DataBufferLast != null)
{
Buffer.BlockCopy(DataBufferLast, 0, TempBytes, 0,

DataBufferSizeLast);
iTempDataBufferSizeLast = DataBufferSizeLast;
DataBufferLast = null;   //---- 使用完后 为空值
DataBufferSizeLast = 0;
}
Buffer.BlockCopy(DataBuffer, 0, TempBytes, iTempDataBufferSizeLast,

receivedBytesCount);
EncodingBytes(TempBytes, receivedBytesCount +

iTempDataBufferSizeLast);
}
catch (SocketException e)
{
//10035 == WSAEWOULDBLOCK
if (e.NativeErrorCode.Equals(10035))
{
//仍然处于连接状态,但是发送可能被阻塞
}
else
{
//连接错误,返回错误代码:e.NativeErrorCode
Socket_e.ResCode = e.NativeErrorCode.ToString();
SocketEvent(this, Socket_e);
return;
}
}
catch (Exception e)
{
//其他错误
Socket_e.ResCode = e.ToString();
SocketEvent(this, Socket_e);
return;
}
}
}


小结

线程通知到上层事件后,外部事件挂接后,可以直接进行委托BeginInvoke(),在委托的方法中就可以直接操作界面控件了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: