【问题标题】:Hitting an http server using Socket使用 Socket 访问 http 服务器
【发布时间】:2011-04-22 00:22:59
【问题描述】:

我正在尝试使用简单的 Socket 而不是使用可用的包装器来访问网络服务器。无论出于何种原因,我都无法让它接收响应。下面的代码有什么问题:

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
        }
    }
}

【问题讨论】:

    标签: .net http sockets


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 2013-01-23
      • 2015-12-07
      • 2016-03-22
      • 2015-06-13
      • 1970-01-01
      • 2013-08-31
      • 1970-01-01
      • 2021-03-22
      • 1970-01-01
      相关资源
      最近更新 更多