大佬快来帮帮我C# socket

weixin_57430610 2021-04-24 04:05:27
我用c# socket获取百度网页,但是总是有各种问题比如do
{ sl = ss.Receive(res, off, 1024, 0);
off += sl;

} while (sl==1024);
和do
{ sl = ss.Receive(res, off, 1024, 0);
off += sl;

} while (ss.Available>0);
获取不到完整网页,大概能读到2880字节就返回了, do
{ sl = ss.Receive(res, off, 1024, 0);
off += sl;

} while (sl>0); 这样可以获取到完整网页但是有一分钟延时,应该怎么弄才行?谢谢各位大佬。
...全文
1174 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
对于Http早期的基本协议来说,如果是短链接的,那么你可以等到 Stream 的 Read 状态被关闭时才开始解析收到的字节。而不是用什么固定长度值去判断是否接收完毕。 但是现在Http 协议已经进入到支持长连接的时代,那么就要根据 RFC 更高级的协议来实际解析 Http 消息。例如第一行文本(以换行作为结束)就可以判断是不是 Post、Get等等类型的消息。对于 Post 消息,那么第一次遇到的“连续两个行结束”就是消息头内容的结束,然后再一次遇到“行结束”则作为消息体的结束。 也就是说,你不能用什么1024来判断页面内容是否结束,而要不断地接收字节,并且随时“根据高层次的协议”来判断一个消息是否遇到了结束标志位置。
  • 打赏
  • 举报
回复
一般来说,Stream的Receive返回的是本地缓冲区里字节个数。例如远端正在传来100万字节,那么你要求一次读取2000字节,这个 Receive函数即可能返回2000,也可能只返回1999甚至199。你不能说“传完了”,这是逻辑错误。
hhsacsb 2021-05-09
  • 打赏
  • 举报
回复
看了半天,原来都是大神在玩底层架构。。。。。那就不打扰了
weixin_57430610 2021-04-27
  • 打赏
  • 举报
回复
引用 8 楼 wanghui0380的回复:
[quote=引用 7 楼 weixin_57430610 的回复:][quote=引用 5 楼 大西瓜大降价一块一斤的回复:]楼上说的好别人造车拿现成的合成一下就好了,你还在造轮子 最简单的获取数据方法

            WebClient wc = new WebClient();
            wc.Encoding = System.Text.Encoding.UTF8;
            string result= wc.DownloadString("http://www.baidu.com");
谢谢,其实我是想知道socket如何接收完数据,我用过c#里面的webclient,它可以很快的获取网页,图片等内容,但我不知道底层怎么实现的,应该也是用socket吧[/quote] 额,也就是说,你就是特地去玩轮子的。 这样我的先去让看书了,嘿嘿,有些人认为让人看书就是鄙视新人。 不过有些东西你不先看书,我们没办法去说后面的东西 比如http协议是个文本协议,分头部head部分和正文部分两块 大多数情况下头部部分有长度,你判定是否接收完毕的判定依据就是这个长度 少数情况下头部不标长度,使用chunked方式,无法确定正文长度,此时通常已服务器断开连接为标准 相关说明 https://blog.csdn.net/yankai0219/article/details/8269922 所以如果这些玩意你不先去瞅瞅http协议头,http封包等基础资料,我们无法向下说明[/quote] 谢谢,我去深入了解一下
  • 打赏
  • 举报
回复
楼上说的好别人造车拿现成的合成一下就好了,你还在造轮子 最简单的获取数据方法

            WebClient wc = new WebClient();
            wc.Encoding = System.Text.Encoding.UTF8;
            string result= wc.DownloadString("http://www.baidu.com");
小贵子88 2021-04-25
  • 打赏
  • 举报
回复
顶一下,好久没来过了
ziqi0716 2021-04-25
  • 打赏
  • 举报
回复
读网页你用socket的操作呢,就相当于,你要去1000公里外的目的地,而你选择自己造交通工具去。而不是使用现成的公共交通,高铁,飞机等。 或者说,你要建房子,正常应该买砖买水泥就行了,而你这个相当于先要建造砖厂,水泥厂等。 你可以先看看socket,tcp,http这些概念,然后再看看httpclient对象。
wanghui0380 2021-04-25
  • 打赏
  • 举报
回复
当然作为一个网页来说,你这样写是不够的。 因为网页按http协议完成,你单纯把他当字节读不是合理写法,你的按http协议去解码 所以我们建议,如果不不是想研究啥是http协议,如果你不是想和博客园学习什么自己造轮子(所谓不造轮子,就不是好程序员系列读物) 请直接使用httpclient
weixin_57430610 2021-04-25
  • 打赏
  • 举报
回复
谢谢,我去深入了解一下
wanghui0380 2021-04-25
  • 打赏
  • 举报
回复
ss.Receive(res, off, 1024, 0) 如果你能理解他的意思,自己写 他的意思是给了1024的buffer,最大能读1024,最小在0到1024之间 也就是如果有8个苹果,每次取3个,问你啥时候取完 当然是取到不够3个时候就取完 所以你的判定条件是 do while(小于1024)
X-i-n 2021-04-25
  • 打赏
  • 举报
回复
网页处理为什么想不开要用socket?HttpWebRequest、WebClient都比那个强得多啊
  • 打赏
  • 举报
回复
底层就是对协议的处理,解释,析构等,原理不复杂,但实现过程是很复杂的,数据块,链表,缓冲池,各类算法...比你造个车可能还复杂。
wanghui0380 2021-04-25
  • 打赏
  • 举报
回复
w3c http1.1 RFC https://www.w3.org/Protocols/rfc2616/rfc2616.html
wanghui0380 2021-04-25
  • 打赏
  • 举报
回复
你看到了,chunked方式下还的继续分keeplive和不keeplive 所以总体上如果你想自己折腾,还有的一搞。最起码你的先把http1.1(w3c http1.1 RFC)协议内容整个通读一遍才能开始动手
wanghui0380 2021-04-25
  • 打赏
  • 举报
回复
引用 7 楼 weixin_57430610 的回复:
[quote=引用 5 楼 大西瓜大降价一块一斤的回复:]楼上说的好别人造车拿现成的合成一下就好了,你还在造轮子 最简单的获取数据方法

            WebClient wc = new WebClient();
            wc.Encoding = System.Text.Encoding.UTF8;
            string result= wc.DownloadString("http://www.baidu.com");
谢谢,其实我是想知道socket如何接收完数据,我用过c#里面的webclient,它可以很快的获取网页,图片等内容,但我不知道底层怎么实现的,应该也是用socket吧[/quote] 额,也就是说,你就是特地去玩轮子的。 这样我的先去让看书了,嘿嘿,有些人认为让人看书就是鄙视新人。 不过有些东西你不先看书,我们没办法去说后面的东西 比如http协议是个文本协议,分头部head部分和正文部分两块 大多数情况下头部部分有长度,你判定是否接收完毕的判定依据就是这个长度 少数情况下头部不标长度,使用chunked方式,无法确定正文长度,此时通常已服务器断开连接为标准 相关说明 https://blog.csdn.net/yankai0219/article/details/8269922 所以如果这些玩意你不先去瞅瞅http协议头,http封包等基础资料,我们无法向下说明
weixin_57430610 2021-04-25
  • 打赏
  • 举报
回复
引用 5 楼 大西瓜大降价一块一斤的回复:
楼上说的好别人造车拿现成的合成一下就好了,你还在造轮子 最简单的获取数据方法

            WebClient wc = new WebClient();
            wc.Encoding = System.Text.Encoding.UTF8;
            string result= wc.DownloadString("http://www.baidu.com");
谢谢,其实我是想知道socket如何接收完数据,我用过c#里面的webclient,它可以很快的获取网页,图片等内容,但我不知道底层怎么实现的,应该也是用socket吧
six2me 2021-04-25
  • 打赏
  • 举报
回复
楼上正解
还可以这么用
WebClient wc = new WebClient();
string uri = "http://www.baidu.com";
Stream stream = wc.OpenRead(uri);
StreamReader sr = new StreamReader(stream);
string strLine = "";
while ((strLine = sr.ReadLine()) != null)
{
this.listBox1.Items.Add(strLine);
richTextBox1.AppendText(strLine);
}
sr.Close();

111,096

社区成员

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

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

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