2011-04-22 23 views
1

我想使用一個簡單的套接字而不是使用可用的封裝器來訪問網絡服務器。無論出於何種原因,我無法獲得答覆。下面的代碼有什麼問題:使用套接字打到http服務器

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

回答

0

問題出在我創建的套接字上。它需要是流式TCP連接而不是原始ipv4。

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