为什么使用 WebRequest 发送 post 数据需要这么长时间?

发布于 2024-08-29 11:13:57 字数 3428 浏览 6 评论 0原文

我目前正在创建一个 C# 应用程序来绑定到 php / MySQL 在线系统。应用程序需要将发布数据发送到脚本并获取响应。

当我发送以下数据时,

username=test&password=test  

我得到以下响应...

Starting request at 22/04/2010 12:15:42  
Finished creating request : took 00:00:00.0570057  
Transmitting data at 22/04/2010 12:15:42  
Transmitted the data : took 00:00:06.9316931       <<--
Getting the response at 22/04/2010 12:15:49  
Getting response 00:00:00.0360036  
Finished response 00:00:00.0360036  
Entire call took 00:00:07.0247024  

如您所见,实际将数据发送到脚本需要 6 秒,我已经通过从 telnet 发送数据和从本地发送 post 数据进行了进一步测试文件到 URL,他们甚至不需要一秒钟,所以这不是网站上托管脚本的问题。

为什么传输两个简单字符串的数据需要 6 秒?

我使用自定义类来发送数据

class httppostdata
{
    WebRequest request;
    WebResponse response;

    public string senddata(string url, string postdata)
    {
        var start = DateTime.Now;
        Console.WriteLine("Starting request at " + start.ToString());

        // create the request to the url passed in the paramaters
        request = (WebRequest)WebRequest.Create(url);


        // set the method to post
        request.Method = "POST";
        // set the content type and the content length
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = postdata.Length;
        // convert the post data into a byte array
        byte[] byteData = Encoding.UTF8.GetBytes(postdata);
        var end1 = DateTime.Now;
        Console.WriteLine("Finished creating request : took " + (end1 - start));

        var start2 = DateTime.Now;
        Console.WriteLine("Transmitting data at " + start2.ToString());
        // get the request stream and write the data to it
        Stream dataStream = request.GetRequestStream();
        dataStream.Write(byteData, 0, byteData.Length);
        dataStream.Close();
        var end2 = DateTime.Now;
        Console.WriteLine("Transmitted the data : took " + (end2 - start2));


        // get the response
        var start3 = DateTime.Now;
        Console.WriteLine("Getting the response at " + start3.ToString());


        response = request.GetResponse();
        //Console.WriteLine(((WebResponse)response).StatusDescription);
        dataStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(dataStream);
        var end3 = DateTime.Now;
        Console.WriteLine("Getting response " + (end3 - start3));

        // read the response
        string serverresponse = reader.ReadToEnd();
        var end3a = DateTime.Now;
        Console.WriteLine("Finished response " + (end3a - start3));

        Console.WriteLine("Entire call took " + (end3a - start));

        //Console.WriteLine(serverresponse);
        reader.Close();
        dataStream.Close();
        response.Close();

        return serverresponse;
    }
}

并调用它我使用

private void btnLogin_Click(object sender, EventArgs e)
{
    // string postdata;

    if (txtUsername.Text.Length < 3 || txtPassword.Text.Length < 3)
    {
        MessageBox.Show("Missing your username or password.");
    }
    else
    {
        string postdata = "username=" + txtUsername.Text +
                          "&password=" + txtPassword.Text;

        httppostdata myPost = new httppostdata();
        string response = myPost.senddata("http://www.domainname.com/scriptname.php", postdata);
        MessageBox.Show(response);
    }
}

I am currently creating a C# application to tie into a php / MySQL online system. The application needs to send post data to scripts and get the response.

When I send the following data

username=test&password=test  

I get the following responses...

Starting request at 22/04/2010 12:15:42  
Finished creating request : took 00:00:00.0570057  
Transmitting data at 22/04/2010 12:15:42  
Transmitted the data : took 00:00:06.9316931       <<--
Getting the response at 22/04/2010 12:15:49  
Getting response 00:00:00.0360036  
Finished response 00:00:00.0360036  
Entire call took 00:00:07.0247024  

As you can see it is taking 6 seconds to actually send the data to the script, I have done further testing bye sending data from telnet and by sending post data from a local file to the url and they dont even take a second so this is not a problem with the hosted script on the site.

Why is it taking 6 seconds to transmit the data when it is two simple strings?

I use a custom class to send the data

class httppostdata
{
    WebRequest request;
    WebResponse response;

    public string senddata(string url, string postdata)
    {
        var start = DateTime.Now;
        Console.WriteLine("Starting request at " + start.ToString());

        // create the request to the url passed in the paramaters
        request = (WebRequest)WebRequest.Create(url);


        // set the method to post
        request.Method = "POST";
        // set the content type and the content length
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = postdata.Length;
        // convert the post data into a byte array
        byte[] byteData = Encoding.UTF8.GetBytes(postdata);
        var end1 = DateTime.Now;
        Console.WriteLine("Finished creating request : took " + (end1 - start));

        var start2 = DateTime.Now;
        Console.WriteLine("Transmitting data at " + start2.ToString());
        // get the request stream and write the data to it
        Stream dataStream = request.GetRequestStream();
        dataStream.Write(byteData, 0, byteData.Length);
        dataStream.Close();
        var end2 = DateTime.Now;
        Console.WriteLine("Transmitted the data : took " + (end2 - start2));


        // get the response
        var start3 = DateTime.Now;
        Console.WriteLine("Getting the response at " + start3.ToString());


        response = request.GetResponse();
        //Console.WriteLine(((WebResponse)response).StatusDescription);
        dataStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(dataStream);
        var end3 = DateTime.Now;
        Console.WriteLine("Getting response " + (end3 - start3));

        // read the response
        string serverresponse = reader.ReadToEnd();
        var end3a = DateTime.Now;
        Console.WriteLine("Finished response " + (end3a - start3));

        Console.WriteLine("Entire call took " + (end3a - start));

        //Console.WriteLine(serverresponse);
        reader.Close();
        dataStream.Close();
        response.Close();

        return serverresponse;
    }
}

And to call it I use

private void btnLogin_Click(object sender, EventArgs e)
{
    // string postdata;

    if (txtUsername.Text.Length < 3 || txtPassword.Text.Length < 3)
    {
        MessageBox.Show("Missing your username or password.");
    }
    else
    {
        string postdata = "username=" + txtUsername.Text +
                          "&password=" + txtPassword.Text;

        httppostdata myPost = new httppostdata();
        string response = myPost.senddata("http://www.domainname.com/scriptname.php", postdata);
        MessageBox.Show(response);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

九命猫 2024-09-05 11:13:57

确保将 WebRequest 的代理属性显式设置为 null,否则它将尝试自动检测代理设置,这可能需要一些时间。

Make sure you explicitly set the proxy property of the WebRequest to null or it will try to autodetect the proxy settings which can take some time.

顾铮苏瑾 2024-09-05 11:13:57

很可能是因为,在您的测试中,您只调用一次,您看到的延迟是 C# 代码被 JIT 编译的结果。

更好的测试是调用两次,并丢弃第一次的计时,看看它们是否更好。

更好的测试是放弃第一组计时,然后运行多次并取平均值,尽管对于非常宽松的“指示性”视图,这可能没有必要。

顺便说一句,对于这种计时,您最好使用 System.Diagnostics.Stopwatch 类而不是 System.DateTime 。

[编辑]
另外,请注意 Mant101 关于代理的建议,如果设置无代理无法解决问题,您可能希望设置 Fiddler 并设置您的请求以使用 Fiddler 作为其代理。这将允许您拦截实际的 http 调用,以便您可以从框架外部更好地细分 h​​ttp 调用计时本身。

Chances are that because, in your test, you only call this once, the delay you see is the C# code being JIT compiled.

A better test would be to call this twice, and discard the timings from the first time and see if they are better.

An even better test would be to discard the first set of timings, and then run this many times and take an average, although for a very loose "indicative" view, this is probably not necessary.

As an aside, for this sort of timing, you are better off using the System.Diagnostics.Stopwatch class over System.DateTime.

[EDIT]
Also, noting Mant101's suggestion about proxies, if the setting no proxy fails to resolve things, you may wish to set up Fiddler and set your request to use Fiddler as its proxy. This would allow you to intercept the actual http calls so you can get a better breakdown of the http call timings themselves from outside the framework.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文