使用socket类进行web服务器的访问,由于其它情况不能使用更高级的类,向服务器发送数据后,服务器返回包的个数不定(根据页面情况而定),我怎样知道这个页面已经接收完毕?
string ss;
while(true)
{
    byte[] recvBytes = new byte[1024];
    bytes = c.Receive(recvBytes);
       ss = ss+bytes.tostring();
}
我用这个循环读取,接收到包后都存在ss中,可不知道什么时候就收完了?

解决方案 »

  1.   

    有人采用,如下形式接收数据:
    while(true) 

    bytes=socket.Receive(recvBytes,recvBytes.Length,0); 
    //读取完成后退出循环 
    if(bytes<=0) 
    break; 
    //将读取的字节数转换为字符串 
    recvStr+=Encoding.ASCII.GetString(recvBytes,0,bytes); 
    } 但这里面关键点是if(bytes<=0) ,根据MSDN及我的试验,会处于阻止状态,不会返回<0的数。
    MSDN:如果没有可读取的数据,则 Receive 方法将一直处于阻止状态,直到数据可用,除非使用 Socket.ReceiveTimeout 设置了超时值。如果超过超时值,Receive 调用将引发 SocketException。
      

  2.   

    Socked对象的Available属性+ ReceiveTimeout就可以判断时候接收完毕了,但是这样也不能百分之百的判断出。
    我个人认为要用套接字进行通讯,那么最好还是自己定义数据帧,自己组织数据包进行传递,除非是使用大家都已经熟悉的UDP、HTTp传输协议,否则是一件很痛苦的事情!!
      

  3.   

    ss = ss+bytes.tostring(); //这个不行吧.
    一般来讲,你可以先接受200-300个byte,这些基本上是http头。
    你先把这些字节转化为string(使用gb2312编码转化,也可以尝试其他的编码)。
    然后分行读取,每行检测相关http头信息。
    http头里边有个Content-Length:的属性,//aline为其中的一行
    int jj = aline.IndexOf("Content-Length:");
    int ee = aline.Length - 15; 
    lenstr = aline.Substring(15, ee);
    lenst = Int32.Parse(lenstr);   //得到正文长度,也就是html文件源代码的长度
    然后,你再检测空行(因为http头和正文之间使用空行分开)。
    在接下来,你就可以用lenst来接受正文的长度了。
    值得注意的是,有可能,http头假如只有234个字节,那么,第一次你接受的300个字节中已经含有了部分正文信息,
    那么你再次需要接受的字节数应该是:lenst-(300-234).
      

  4.   

    TO:zzultc.你说的方法可以一试!不过不如给一个大些的缓冲区,4096的?这样一般情况可以不用在循环,能一次读完就一次读完。
    TO:myjce。谢谢你的提醒,我是要用在互联网的情况下,网络条件不定。但服务器端是标准的WEB服务器,不能加4个字节。另外你所说的,就算加4个字节的包长度,在网络条件差的情况下,也没办法完整接收啊,应该另外还有错误处理的办法吧?
      

  5.   

    最好用自定义协议来解决。例如数据包大小的标记或者学http,stmp,两个换行符来表示
    数据收不到,要么等,要么要求重发了
    .net Q群:2415097
      

  6.   

    哈哈,我采用了楼下2的做法使用Socked对象的Available属性,结合循环,经测试就可行的,谢谢楼2了,我的问题也解决了