Производительность сокетов C #?проблемы при ожидании ответа от сервера - PullRequest
0 голосов
/ 05 июля 2011

В настоящее время мне немного любопытно следующее:

При попытке запросить страницу с сервера это обычно занимает несколько секунд, это можно подтвердить через веб-браузер или w./e.

Я пытался сделать это с сокетами:

            string pData = "GET / HTTP/1.1\r\n" +
                       "Host: www.google.com\r\n" +
                       "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1\r\n" +
                       "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
                       "Accept-Language: en-us,en;q=0.5\r\n" +
                       "Accept-Encoding: deflate\r\n" +
                       "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" +
                       "Keep-Alive: 115\r\n" +
                       "Connection: keep-alive\r\n\r\n";
        string[] a = CreateSocketRequest("www.google.com", 80, pData, 4);
        Console.WriteLine(a[0] + "\r\n" + a[1]);

Примечание: вызов CreateSocketRequest возвращает массив строк с заголовками в индексе 0 и содержимомв индексе 1. Кроме того, код, стоящий за ним, работает отлично.

Во всяком случае, забавный момент с вышеупомянутым пакетом запроса заключается в том, что, когда запрос сделан, ответа, по-видимому, нет, фактическиприостановить отладку на некоторое время, а затем возобновить программу, чтобы увидеть ответ, записанный на консоль.

Так что мне потребовалось как безумное количество часов, чтобы найти виновного:

HTTP/1.1

При всем моем изумлении и потраченном времени, например, нужно изменить это на:

HTTP/1.0

И, в общем, ответ почти мгновенно записывается на консоль, нетЗадержки, ничего, так же, как это должно работать.

Мой вопрос будет таким: почему это занимает так много времени с HTTP / 1.1 в заголовке, а HTTP / 1.0 делает это мгновенно?Я был бы признателен, если бы кто-то мог пролить свет на этот вопрос или хотя бы указать мне правильное направление.

Примечание 1: Я забыл упомянуть, но, делая те же запросы, используяTcpClient и NetworkStream приводят к одинаковой низкой производительности, но WebClient сделал это мгновенно (не тестировал с использованием HttpWebRequest).

Примечание 2: Метод CreateSocketRequest (не завершен, но это должно в значительной степенидать вам представление):

    private const int BufferSize = 1024;
    public static string[] CreateSocketRequest(string host, int port, string requestData, int bufferMultiplication = 2)
    {
        Socket s = ConnectSocket(host, port);
        // Send the Data
        s.Send(Encoding.ASCII.GetBytes(requestData));

        // Receive the Response
        ArrayList al = new ArrayList(BufferSize * (bufferMultiplication * 4));
        byte[] receivedBytes = new byte[BufferSize * bufferMultiplication];
        int bytes;

        try {
            while ( (bytes = s.Receive(receivedBytes, 0, receivedBytes.Length, SocketFlags.None)) > 0 )
                al.AddRange(bytes.Equals(BufferSize) ? receivedBytes : TakeBytes(receivedBytes, bytes));
        } catch ( SocketException se ) {
            // Write to log
            Console.WriteLine(se.Message);
        } finally {
            s.Close();
            s.Dispose();
        }

        receivedBytes = (byte[])al.ToArray(typeof(Byte));
    //
    // Convert to string and all that etc.
    //

1 Ответ

0 голосов
/ 05 июля 2011

Я не смог найти CreateSocketRequest, но при использовании HttpWebRequest мне удалось получить ответ за 0,145 секунды:

HTTP Protocol Version: 1.1

Headers: Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
Date: Tue, 05 Jul 2011 06:16:09 GMT
Expires: -1
Set-Cookie: PREF=ID=4bd33e8b133134b4:FF=0:TM=1309846569:LM=1309846569:S=ZT2NPRNq
yYBcgSmY; expires=Thu, 04-Jul-2013 06:16:09 GMT; path=/; domain=.google.com,NID=
48=VwNz5I8Y_Pf51hGWUE38wq1YNb5-OOkPD-9V36tXHkLtitJea8pyO6MLB-wm6lpRmLDyDIiNuoklC
SldpfXFqNWKeKM6P4hIXudtUsEHiMiRICNf5ZUOmQbz1htShb8G; expires=Wed, 04-Jan-2012 06
:16:09 GMT; path=/; domain=.google.com; HttpOnly
Server: gws
X-XSS-Protection: 1; mode=block
Transfer-Encoding: chunked


Duration: 0.145 seconds

Код выглядит так:

static void Main(string[] args)
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.google.com:80/");
    Console.WriteLine("HTTP Protocol Version: " + request.ProtocolVersion + "\n");

    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    Console.WriteLine("Headers: \n" + response.Headers);
    sw.Stop();

    Console.WriteLine("Duration: {0} seconds", sw.ElapsedMilliseconds / 1000.0);
    Console.ReadKey();
}

Как я уже сказал, я не смог найти метод CreateSocketRequest ни в одной из библиотек .NET 4.0, поэтому, если вы написали этот метод, пожалуйста, предоставьте для него код. Если это что-то из другой библиотеки, то я не знаю, смогу ли я вам чем-нибудь помочь. Кроме того, я не просмотрел все заголовки, которые вы указали в своем запросе, но я предполагаю, что там нет ничего конкретного, что могло бы вызвать задержку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...