Загрузка сайта с использованием сокетов - PullRequest
3 голосов
/ 10 октября 2011

Я пытаюсь скачать исходники сайта с помощью сокетов.В настоящее время я могу загрузить заголовки, и после этого я просто разрываю соединение, потому что я не знаю, как долго я должен получать данные.Это код:

    private void HandleConnect(SocketAsyncEventArgs e)
    {
        if (e.ConnectSocket != null)
        {
            // simply start sending
            bool completesAsynchronously = e.ConnectSocket.SendAsync(e);

            // check if the completed event will be raised.
            // if not, invoke the handler manually.
            if (!completesAsynchronously)
            {
                SocketAsyncEventArgs_Completed(e.ConnectSocket, e);
            }
        }
    }

    private void HandleReceive(SocketAsyncEventArgs e)
    {
        string responseL = Encoding.UTF8.GetString(e.Buffer, 0, e.Buffer.Length);
        response += responseL;
        temp += responseL;

        string[] lines = Regex.Split(response, "\r\n\r\n");
        if (lines.Length > 1 && header == "")
        {
            header = lines[0].ToString() + "\r\n";
            lines[0] = "";
            response = lines.ToString();
        }
        if (header == "")
        {
            bool completesAsynchronously = e.ConnectSocket.ReceiveAsync(e);
        }
        else
        {
            System.Windows.Deployment.Current.Dispatcher.BeginInvoke(delegate()
            {
                _callback(false, this);
            });
        }
    }

Я пытался найти \ r \ n, но это не помогло: /

Пожалуйста, помогите!

Спасибозаранее:)

Ответы [ 2 ]

3 голосов
/ 10 ноября 2011

Я использую этот код для отправки заголовков на сайт, а затем для чтения его содержимого. Я надеюсь, что вы найдете это полезным.

        ReadStateObject stateObject; //Info below
        mytcpclient = new TcpClient();
        mytcpclient.Connect(host, port);
        mysocket = mytcpclient.Client;
        SendHeader(mysocket);//Info below
        ns = mytcpclient.GetStream();
        if (ns.CanRead)
        {
            stateObject = new ReadStateObject(ns, 1024);
            ns.BeginRead(stateObject.ReadBuffer, 0, stateObject.ReadBuffer.Length, new AsyncCallback(ReadCallBack), stateObject);
        }

StateObject - это небольшой класс, используемый для представления объекта AsyncState в методе BeginRead:

class ReadStateObject
{
    public NetworkStream Stream {get; set;}
    public byte[] ReadBuffer;

    public ReadStateObject(NetworkStream _stream, int bufferSize)
    {
        Stream = _stream;
        ReadBuffer = new byte[bufferSize];
    }
}

И это метод обратного вызова, используемый в методе BeginRead.

    private void ReadCallBack(IAsyncResult result)
    {
        ReadStateObject stateObject = (ReadStateObject)result.AsyncState;
        NetworkStream myNetworkStream = stateObject.Stream;
        int numberofbytesread = 0;
        StringBuilder sb = new StringBuilder();
        numberofbytesread = myNetworkStream.EndRead(result);
        sb.Append(Encoding.ASCII.GetString(stateObject.ReadBuffer, 0, numberofbytesread));

        /*It seems, if there is no delay, the DataAvailable may not be true even when there are still data to be received from the site, so I added this delay. Any suggestions, how to avoid this are welcome*/

        Thread.Sleep(500);

            while (myNetworkStream.DataAvailable)
            {
                byte[] mydata = new byte[1024];
                numberofbytesread = myNetworkStream.Read(mydata, 0, mydata.Length);
                sb.Append(Encoding.ASCII.GetString(mydata, 0, numberofbytesread)); 

            }

      Console.Writeln(sb.ToString());
        mytcpclient.Close();
    }

И именно здесь заголовки отправляются на сайт

    public void SendHeader(Socket mySocket)
    {
        String sBuffer = "";
        sBuffer = sBuffer + "GET /"+pathquery+" HTTP/1.1" + "\r\n";
        sBuffer = sBuffer + "Host: "+ hostname + "\r\n";
        sBuffer = sBuffer + "Content-Type: text/html\r\n";
        sBuffer = sBuffer + "\r\n";
        Byte[] bSendData = Encoding.ASCII.GetBytes(sBuffer);
        mySocket.Send(Encoding.ASCII.GetBytes(sBuffer), Encoding.ASCII.GetBytes(sBuffer).Length, 0);
    }
1 голос
/ 10 октября 2011

Возможно, вы должны использовать WebClient или HttpWebRequest вместо сокетов. Использование сокетов и интерпретация протокола Http могут быть болезненными.

...