Socket接收的数据不全是怎么一回事?单步执行就可以全部接收

liefeng999 2009-04-14 10:00:12
这是代码:


public static void SendRecive(string host, byte[] msg, ref string HttpResponse)
{
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Blocking = true;
s.ReceiveTimeout = -1;
//Socket d=new Socket((AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{

s.Connect(host, 80);
s.Send(msg);
byte[] msgout = new byte[1000];
Encoding gbk = Encoding.GetEncoding(936);
int i = 0;
while(true)
{
Array.Clear(msgout, 0, 1000);

i = s.Receive(msgout, msgout.Length, SocketFlags.None);
HttpResponse += gbk.GetString(msgout);
if (i <= 0) break;

}
}
catch (Exception e) {

Console.WriteLine("Exception caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
s.Shutdown(SocketShutdown.Receive);
s.Close();
}


这种情况,有时能接收到1000个字符,有时2000字符
但是如果是单步调试,就可以收到全部(大概是8000个字符左右)
不知为什么会这样,在这里卡了很久,希望csdn能给我些帮助,谢谢!
...全文
189 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
你网络可能充斥了ARP之类的广播风暴,比如路由器的连接有问题或者有多个相互竞争的网络服务之类的。这个时候,比如说发送端一次发送10k数据,接收端可能接收到2k,这时候 i==0 成立。可是假设你再重试几次,就有能继续接收数据了。

网络通讯要设计明确的通讯协议,什么时候算是接收结束,不仅仅要看是否 i==0,还要看是否你接收到的数据恰好以结束标志来结束!
刘志伟_ 2011-07-07
  • 打赏
  • 举报
回复
个人感觉是不是应该先把所有的字节接收完成之后,再用 gbk.GetString(msgout)转化成字符串。因为并不保证你每次接收的字节正好成够成字字符串的正确编码
zhumingfang 2011-07-07
  • 打赏
  • 举报
回复
这个就是数据的粘包问题
你可以把数据缓存设大点,这个是置标不置本
HMBOA 2011-07-07
  • 打赏
  • 举报
回复
问题解决了没···我跟你遇到了类似的问题~~
qhiou 2011-07-07
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 qhiou 的回复:]

最简单的做法就是规定一个特殊字符作为结束符(如EOF),不要使用长度为0判断跳出,判断接收到结束符认为本次报文结束。否则无法解决这个问题。
[/Quote]
通常的商用通讯组件(IPworks、tuxedo等)都是使用结束符来保证报文完整的,同时还可以在报文指定位置加入MAC校验为来保证报文未被篡改。
qhiou 2011-07-07
  • 打赏
  • 举报
回复
最简单的做法就是规定一个特殊字符作为结束符(如EOF),不要使用长度为0判断跳出,判断接收到结束符认为本次报文结束。否则无法解决这个问题。
dreamrising 2011-07-07
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 sp1234 的回复:]
你网络可能充斥了ARP之类的广播风暴,比如路由器的连接有问题或者有多个相互竞争的网络服务之类的。这个时候,比如说发送端一次发送10k数据,接收端可能接收到2k,这时候 i==0 成立。可是假设你再重试几次,就有能继续接收数据了。

网络通讯要设计明确的通讯协议,什么时候算是接收结束,不仅仅要看是否 i==0,还要看是否你接收到的数据恰好以结束标志来结束!
[/Quote]就这个了。
xu_2007 2011-07-07
  • 打赏
  • 举报
回复
楼主这种情况应该是属于分包情况,就向楼上SP1234大侠说的不错,你应该定义自己的协议来检查每次的数据接收是否完全接收到,如果没有完全接收完则需要将这次接收的数据临时保存在一个地方后再次接收余下的数据,直到接收完全后才重组这几次接收的数据为一条完整的数据!不过还是希望楼主朋友在开发网络程序的时候最好先了解下基础知识,要不然后面的问题会更多,比如什么粘包等等的!
liefeng999 2009-04-14
  • 打赏
  • 举报
回复
相当怪异的事发生了:

当我把 Array.Clear(msgout, 0, 1000),去掉时,则不单步执行也可以收到几乎所有的数据(不过会少了最后一点点数据(为什么为什么?)
当我再把byte[] msgout = new byte[1000];变为byte[] msgout = new byte[1024];又只有一点点数据,这是为什么?怎么会发生这么怪异的事!!!
liefeng999 2009-04-14
  • 打赏
  • 举报
回复
什么缓存大小?怎么看?

当数据长度小于等于0不就表示没有数据可收了吗?
hxdljk 2009-04-14
  • 打赏
  • 举报
回复
你定义的数组时1000,可以收到8000个么,看看你的缓存大小,
if (i <= 0) break;
当收到的数据长度小于0时就推出么?
liefeng999 2009-04-14
  • 打赏
  • 举报
回复
怎么没人帮我啊!!
liefeng999 2009-04-14
  • 打赏
  • 举报
回复
up
liefeng999 2009-04-14
  • 打赏
  • 举报
回复
up
liefeng999 2009-04-14
  • 打赏
  • 举报
回复
晕,还是没人来,继续

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧