积极答复者
TcpClient is not reliable

问题
-
i used tcpclient receive data , but i find that tcpclient.avaliable is not reliable,sometimes the Avaliable<0,but the data is valiable in factly.
so,when i recieve large data ,it will loss.
private void Read(StringBuilder sb)
{
List<byte> bytesList = new List<byte>();
NetworkStream ns = tcpCli.GetStream();
while (tcpCli.Available > 0)
{
int input = ns.ReadByte();
//将byte加入List中
bytesList.Add((byte)input);
}
byte[] bytes = new byte[bytesList.Count];
bytesList.CopyTo(bytes);
sb.Append(textEncoder.GetString(bytes));
}
答案
-
不是很清楚你们的通信协议是怎么搞的。。
首先,服务端应该提供通信协议格式,例如前两位,或者前四位是长度,后面试什么标志之类的。觉得你现在根本就是在猜。
可以参考一下 Google Protocol Buffers, 网络上传输数据。。通常都不是 Covert.ToString 然后再传输的。。所以你 Encoding.GB2132.Getstring 然后查找文本却找不到,那是正常的。。并不代表它不存在。
PS: 如果服务端真的只发一堆 String,而没有任何控制信息。也只能够对着来收,收到就收,收不到就让服务器重发。。至于收错了,那是正常的事情。
学习学习....- 已标记为答案 Leo Liu - MSFTModerator 2011年6月9日 2:18
全部回复
-
对你的情况有一些不明白的地方。。
根据个人的使用经验, Avaliable 从来未出现小于 0 的情况,即使是一次过传一个 1.x G 的文件亦未曾出错。
观察了一下你的代码,也未发现有捕捉 Available < 0 的代码存在。。
所以不是很清楚。。为何你那么肯定地认为 Available 不可靠了。 是否是通过观察发送发发了 100M 的数据。但只接受到 90M,从而断定不可靠的?或者说是通过断点侦测的?
其实。。感觉你的读数据方法是有问题的,这个程序成立的前提就是能够源源不断地接受到数据。。如果出现一瞬间的网络阻塞,或者发送方出现一瞬间的阻塞, while 循环就会中断。 后面的内容自然收不到了。
学习学习.... -
IGabriel
谢谢你的回答。
为什么出现这种情况,我也感觉很奇怪,但我经过测试确实是有这种情况。
服务端发送过来的字节是8910000个字节,但是tcpclient.ReceiveBufferSize默认的大小是8192
NetworkStream ns = tcpCli.GetStream();
while (tcpCli.Available > 0) //此时Avaliable 的值是8192
{
int input = ns.ReadByte(); //执行该句之后,如果传输的字节小于或等于ReceiveBufferSize的大小,Avaliable会减1.但是接收的字节数大于ReceiveBufferSize,所以执 //行该句之后ReceiveBufferSize还是8192
bytesList.Add((byte)input);
}
byte[] bytes = new byte[bytesList.Count]; //在此处设置断点,当程序跳出循环后,我发现tcpCli.Available >0。所以我的推测是可能由于资源占用比较忙,缓冲区的数据正好读完,但是后续的数据没有进入缓冲区,所以在判断的Available的那个时刻,Avaliable=0,所以跳出了循环。当跳出循环之后,后续的数据又进入了缓冲区,所以Avaliable又>0。 -
不是很清楚你们的通信协议是怎么搞的。。
首先,服务端应该提供通信协议格式,例如前两位,或者前四位是长度,后面试什么标志之类的。觉得你现在根本就是在猜。
可以参考一下 Google Protocol Buffers, 网络上传输数据。。通常都不是 Covert.ToString 然后再传输的。。所以你 Encoding.GB2132.Getstring 然后查找文本却找不到,那是正常的。。并不代表它不存在。
PS: 如果服务端真的只发一堆 String,而没有任何控制信息。也只能够对着来收,收到就收,收不到就让服务器重发。。至于收错了,那是正常的事情。
学习学习....- 已标记为答案 Leo Liu - MSFTModerator 2011年6月9日 2:18