c# - 如何通过 TcpClient 获取页面?

标签 c# http tcp httpwebrequest tcpclient

我正在尝试通过 TCP 流向页面发送 GET 请求。

这是我的代码:

public class SocketLevelWebClient
{
    public string SendWebRequest(string url, string request)
    {
        using(TcpClient tc = new TcpClient())
        {
            tc.Connect(url, 80);

            using (NetworkStream ns = tc.GetStream())
            {
                using (System.IO.StreamWriter sw = new System.IO.StreamWriter(ns))
                {
                    using (System.IO.StreamReader sr = new System.IO.StreamReader(ns))
                    {
                        sw.Write(request);
                        sw.Flush();
                        return sr.ReadToEnd();
                    }
                }
            }
        }
    }

请求本身:

            SocketLevelWebClient wc = new SocketLevelWebClient();
            var r=wc.SendWebRequest("www.youtube.com",@"GET http://www.youtube.com/ HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*
Accept-Language: en-US
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Host: www.youtube.com"+"\r\n\r\n");

当我调用这段代码时,它总是死机等待服务器的响应。

我做错了什么?

最佳答案

问题是 ReadToEnd 仅在流结束时返回。不幸的是,服务器使 TCP 连接保持事件状态。因此 ReadToEnd 永远无法检测到真正的结束已经到来。

证明:

                        sw.Write(request);
                        sw.Flush();
                        var l = sr.ReadLine();

l 正在填充请求的第一行。

删除 keep-alive header 并添加:

Connection: close

或者使用响应的 Content-Length 头来正确读取它(二进制)。

关于c# - 如何通过 TcpClient 获取页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12121912/

相关文章:

python - 为数据存储中存储的图像发送 "304 Not Modified"

networking - VPN 客户端是如何工作的?

c# - 在 2 个监听器之间桥接异步全双工 TCP 通信

c# - 包含字节数组的 xml 问题

http - 多个 HTTP 授权 header ?

c# - 什么是 session Cookie?

.net - http连接重用

c# - Unity TCP 服务器/客户端

c# - F# 声明的命名空间在 c# 项目中不可用或通过对象浏览器可见

c# - 文件已在使用 FileAccess C#