[C#] NetworkStream.Write()存在严重bug


NetworkStream.Write()方法实际上是不可用的,因为它无法保证数据的连续性。


先给大家看一段代码:

//cln is an instance of TcpClient
NetworkStream st = cln.GetStream();
st.Write(tosend, 0, tosend.Length);

这属于NetworkStream.Write()的标准调用方法。可是在catch到IOException之后,我们就会遇上大麻烦。
MSDN上没有对NetworkStream抛出的IOException做详细说明,因此我们只能参考它的基类Stream抛出的IOException的说明,MSDN上是这样说的:If an exception occurs, the position within the stream remains unchanged.

听起来很不错是不是?抓到IOException之后,再重新发送就可以了。可事实并不是这样的。事实是:当NetworkStream.Write()抛出一个IOException的时候,谁也不知道到底有多少个字节已经被发送出去了!
我们用了两天的时间来追踪数据重复的问题,最终的结果让人非常恼火。微软的NetworkStream没有做到他在MSDN里面承诺的“If an exception occurs, the position within the stream remains unchanged.”。

没办法,只能用下面这个方法凑合了:

NetworkStream st = cln.GetStream();
IAsyncResult ar = st.BeginWrite(tosend, 0, tosend.Length, null, null);
if(!ar.AsyncWaitHandle.WaitOne())
{
  ErrorLog.WriteError("fail to wait");
}
st.EndWrite(ar);

至少目前看来NetworkStream.BeginWrite()抛出的异常还是比较准确的。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值