使用Socket命中http服务器

时间:2011-04-22 00:22:59

标签: .net http sockets

我试图使用简单的Socket而不是使用可用的包装器来访问Web服务器。无论出于何种原因,我无法接受回复。以下代码有什么问题:

class Program
{
    static void Main(string[] args)
    {
        SocketConnection connection;
        if (SocketConnection.TryCreate("http://www.bing.com/", out connection))
        {
            connection.Execute().WaitOne();
        }
    }
}

public class StateObject
{
    public Socket WorkingSocket
    {
        get;
        set;
    }

    public const int BufferSize = 256;
    public byte[] buffer = new byte[BufferSize];
    public StringBuilder sb = new StringBuilder();
}

public class SocketConnection
{
    private Uri uri;
    private IPAddress address;

    private ManualResetEvent waithandle = new ManualResetEvent(false);
    private const int bytesInKilobyte = 1024;
    private byte[] recieveBuffer = new byte[bytesInKilobyte];
    private string recievedText = String.Empty;

    public string Result
    {
        get;
        private set;
    }

    private SocketConnection() { }

    public static bool TryCreate(string url, out SocketConnection connection)
    {
        Uri uri = null;

        bool result = Uri.TryCreate(url, UriKind.Absolute, out uri);
        if (result)
        {
            connection = new SocketConnection { uri = uri };
        }
        else
        {
            connection = null;
        }

        return result;
    }

    public WaitHandle Execute()
    {
        Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IPv4);
        socket.DontFragment = true;
        socket.SendBufferSize = 0;
        IPEndPoint endpoint = new IPEndPoint(Dns.Resolve(this.uri.Host).AddressList[0], this.uri.Port);
        socket.BeginConnect(endpoint, this.OnEndConnect, new StateObject { WorkingSocket = socket });
        return this.waithandle;
    }

    private void OnEndConnect(IAsyncResult result)
    {
        StateObject state = (StateObject)result.AsyncState;
        state.WorkingSocket.EndConnect(result);

        StringBuilder sb = new StringBuilder();
        sb.Append("GET ");
        sb.Append(this.uri.PathAndQuery);
        sb.Append(" HTTP/1.1\r\n\r\n");

        byte[] dataToSend = Encoding.ASCII.GetBytes(sb.ToString());
        ArraySegment<byte> segment = new ArraySegment<byte>(dataToSend);
        state.WorkingSocket.BeginSend(new[] { segment }, SocketFlags.None, this.OnEndSend, state);
    }

    private void OnEndSend(IAsyncResult result)
    {
        StateObject state = (StateObject)result.AsyncState;
        int count = state.WorkingSocket.EndSend(result);

        state.WorkingSocket.BeginReceive(recieveBuffer, 0, recieveBuffer.Length, SocketFlags.None, new AsyncCallback(this.OnEndReceive), state);
    }

    private void OnEndReceive(IAsyncResult result)
    {
        StateObject state = (StateObject)result.AsyncState;
        SocketError error;

        int count = state.WorkingSocket.EndReceive(result, out error);
        recievedText += Encoding.UTF8.GetString(this.recieveBuffer, 0, count);
        if (count == recieveBuffer.Length)
        {
            state.WorkingSocket.BeginReceive(recieveBuffer, 0, recieveBuffer.Length, SocketFlags.None, out error, this.OnEndReceive, state);
        }
        else
        {
            this.Result = recievedText;
            this.waithandle.Set();
            // done with request
        }
    }
}

1 个答案:

答案 0 :(得分:0)

问题在于我正在创建的套接字。它需要是流式tcp连接而不是原始ipv4。

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);