求助该如何写一个用localhost的代理服务器!!!
下面是我大致写的代码,我是初学者,想写一个本地的代理服务器(用localhost做代理)。这段代码还没完成,只是停留在读取分析了localhost接收到request的阶段,现在想把request发到服务器上然后接收数据,但是我运行之后基本没反应。后来我试了一下,RequestHandler的DoRequest里面s.Send之后根本Receive不到数据(int bytesRec = s.Receive(bytes)是0);,是我之前s.Connect的时候失败了吗? 如果可以的话,麻烦哪个高人可以发一个可以用的代理代码给我学习一下吗,谢谢了!
using System;using System.Net;using System.Net.Sockets;using System.Threading;namespace LocalProxy{ class Program { static void Main(string[] args) { const int DEFPORTNUM = 8080; int port2use = DEFPORTNUM; const int BACKLOG = 10; // maximum length of pending connections queue Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // Establish the local endpoint for the socket IPAddress ipAddress = IPAddress.Loopback; IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port2use); listener.Bind(localEndPoint); listener.Listen(BACKLOG); System.Console.WriteLine("Listening ... " + localEndPoint.ToString()); while (true) { Socket sock = listener.Accept(); if(sock.Connected) System.Console.WriteLine("Connection established"); RequestHandler rh = new RequestHandler(sock,port2use); Thread rhThread = new Thread(new ThreadStart(rh.DoRequest)); rhThread.Start(); Console.WriteLine(rh.Response); } } }}
using System;using System.Net;using System.Net.Sockets;namespace LocalProxy{ public class RequestHandler { public RequestHandler(string host, int port, string httpVersion, string resource, string requestMethod, string requestHeaders) { Host = host; Port = port; HttpVersion = httpVersion; Resource = resource; RequestMethod = requestMethod; RequestHeaders = requestHeaders; } // RequestHandler public RequestHandler(Socket sock,int port) { System.Text.Encoding utf8 = System.Text.Encoding.UTF8; // Get the HTTP headers first string header = ""; while (true) { byte[] bytes = new byte[1]; int bytesRec = sock.Receive(bytes); header += System.Text.Encoding.ASCII.GetString(bytes, 0, bytesRec); if (header.IndexOf("\r\n\r\n") > -1 || header.IndexOf("\n\n") > -1) { break; } } //System.Console.WriteLine("*** Headers ***\n " + header); // Break up the headers string[] headers = header.Split(new char[] { '\n' }); string requestLine = headers[0]; string[] requestLineElements = requestLine.Split(new char[] { ' ' }); Port = port; RequestMethod = requestLineElements[0]; Resource = requestLineElements[1]; HttpVersion = requestLineElements[2]; Host = getHost(Resource); for (int i = 1; i < headers.Length; i++) { RequestHeaders += headers[i] + "\r\n"; } /* Console.WriteLine("Request method:" + RequestMethod); Console.WriteLine("Resource: " + Resource); Console.WriteLine("HttpVersion:" + HttpVersion); Console.WriteLine("Host: " + Host); Console.WriteLine("Request Headers: \n" + RequestHeaders);*/ } public void DoRequest() { System.Text.Encoding utf8 = System.Text.Encoding.UTF8; const int BUFSZ = 1024; try { // IPAddress and IPEndPoint represent the endpoint that will // receive the request. // Get the first IPAddress in the list using DNS. IPAddress hostadd = Dns.GetHostEntry(Host).AddressList[0]; if ( Host == "localhost" ) { hostadd = IPAddress.Loopback; } IPEndPoint remoteEndPoint = new IPEndPoint(hostadd, Port); //Creates the Socket for sending data over TCP. Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); s.ReceiveTimeout = 6*1000; // Set time out (milliseconds) // Connects to the host using IPEndPoint. s.Connect(remoteEndPoint); Console.WriteLine("Sock connected!"); // Sends the resource request to the host. string getString = RequestMethod + " " + Resource + " " + HttpVersion + "\r\n" + RequestHeaders + "\r\n\r\n"; byte[] getBytes = utf8.GetBytes(getString); s.Send(getBytes, getBytes.Length, SocketFlags.None); Console.WriteLine("socket sent"); // Get the HTTP headers first string header = ""; while (true) { byte[] bytes = new byte[1]; int bytesRec = s.Receive(bytes); header += System.Text.Encoding.UTF8.GetString(bytes,0, bytesRec); if ( header.IndexOf("\r\n\r\n") > -1 || header.IndexOf("\n\n") > -1 ) { break; } } // Break up the headers string[] headers = header.Split(new char[] {'\n'}); // Get the HTTP payload next string data = header; int contentLength = GetContentLength(headers); if ( RequestMethod == "HEAD" ) { contentLength = 0; // no contents for "HEAD" } try { if ( contentLength > 0 ) { int bytesRecd = 0; while ( bytesRecd < contentLength ) { byte[] bytes = new byte[BUFSZ]; int bytesNowGot = s.Receive(bytes); bytesRecd += bytesNowGot; data += System.Text.Encoding.UTF8.GetString(bytes, 0, bytesNowGot); } } else { int bytesNowGot = 0; do { byte[] bytes = new byte[BUFSZ]; bytesNowGot = s.Receive(bytes); data += System.Text.Encoding.UTF8.GetString(bytes, 0, bytesNowGot); } while ( bytesNowGot > 0 ); } } catch (System.Exception) { } Response = data; s.Shutdown(SocketShutdown.Both); s.Close(); } catch (Exception x) { Response = x.ToString(); } } // DoRequest private string getHost(string Resource) { string Host = ""; int index1 = Resource.IndexOf("//") + 2; int index2 = Resource.IndexOf('/', index1); int length = index2 - index1; Host = Resource.Substring(index1, length); return Host; } private static int GetContentLength(string[] headers) { int rval = 0; for ( int i = 1; i < headers.Length; ++i ) // 0 = requestLine { string[] hElem = headers[i].Split(new char[] {':'}); if ( hElem.Length >= 2 ) { if ( hElem[0].Trim().ToLowerInvariant().Equals("content-length") ) { rval = Int32.Parse(hElem[1].Trim()); } } } return rval; } // GetContentLength public string Host { get; private set; } // Host public int Port { get; private set; } // Port public string HttpVersion { get; private set; } // HttpVersion public string Resource { get; private set; } // Resource public string RequestMethod { get; private set; } // RequestMethod public string RequestHeaders { get; private set; } // RequestHeaders public string Response { get; private set; } // Response } // class RequestHandler} // namespace LocalProxy
if (contentLength > 0) { int bytesRecd = 0; while (bytesRecd < contentLength) { byte[] bytes = new byte[BUFSZ]; int bytesNowGot = s.Receive(bytes); for(int i = 0 ; i < bytesNowGot; i++) { ResponseBytesList.Add(bytes[i]); } bytesRecd += bytesNowGot; data += System.Text.Encoding.UTF8.GetString(bytes, 0, bytesNowGot); } } else { int bytesNowGot = 0; do { byte[] bytes = new byte[BUFSZ]; bytesNowGot = s.Receive(bytes); for (int i = 0; i < bytesNowGot; i++) { ResponseBytesList.Add(bytes[i]); } data += System.Text.Encoding.UTF8.GetString(bytes, 0, bytesNowGot); } while (bytesNowGot > 0); } //ResponseBytes = utf8.GetBytes(data); ResponseBytes = ResponseBytesList.ToArray(); clientSock.Send(ResponseBytes);