用C#写的一个最容易最简单的代理服务器,求指教
用C#写的一个最简单最简单的代理服务器,求指教
小弟是初学者,想写一个用localhost,端口8081的最简单最简单代理服务器,代码如下。这个代理纯粹从客户端接收请求然后原封不动发送到服务器,再从服务器接收信息原封不动返回客户端。思路是用两个socket,其中clientSock是连接客户端另一个是连接服务器的,一个List<byte>储存所有接收到的byte然后再传送回clientSock。问题是这个代理反映非常慢,浏览网页也只是偶然可以成功一下。我想知道问题所在,谢谢了!
小弟是初学者,想写一个用localhost,端口8081的最简单最简单代理服务器,代码如下。这个代理纯粹从客户端接收请求然后原封不动发送到服务器,再从服务器接收信息原封不动返回客户端。思路是用两个socket,其中clientSock是连接客户端另一个是连接服务器的,一个List<byte>储存所有接收到的byte然后再传送回clientSock。问题是这个代理反映非常慢,浏览网页也只是偶然可以成功一下。我想知道问题所在,谢谢了!
- C# code
using System; using System.Collections.Generic; using System.Net.Sockets; using System.Net; using System.Threading; namespace LocalhostProxy { class Program { static void Main(string[] args) { const int DEFPORTNUM = 8081; 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); Thread rhThread = new Thread(new ThreadStart(rh.DoRequest)); rhThread.Start(); } } } class RequestHandler { public RequestHandler(Socket sock) { System.Text.Encoding utf8 = System.Text.Encoding.UTF8; List<byte> requestBytesList = new List<byte>(); // Get the HTTP headers first Header = ""; while (true) { RequestBytes = new byte[1]; int bytesRec = sock.Receive(RequestBytes); requestBytesList.Add(RequestBytes[0]); Header += System.Text.Encoding.ASCII.GetString(RequestBytes, 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[] { ' ' }); RequestMethod = requestLineElements[0]; Resource = requestLineElements[1]; HttpVersion = requestLineElements[2]; Uri uri = new Uri(Resource); Host = uri.Host; Port = uri.Port; for (int i = 1; i < headers.Length; i++) { RequestHeaders += headers[i] + "\r\n"; } clientSock = sock; RequestBytes = requestBytesList.ToArray(); /* 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); //Console.WriteLine(remoteEndPoint.ToString()); //Creates the Socket for sending data over TCP. Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); s.ReceiveTimeout = 20 * 1000; // Set time out (milliseconds) // Connects to the host using IPEndPoint. s.Connect(remoteEndPoint); s.Send(RequestBytes, RequestBytes.Length, SocketFlags.None); // Get the HTTP headers first List<byte> ResponseBytesList = new List<byte>(); string header = ""; while (true) { byte[] bytes = new byte[1]; int bytesRec = s.Receive(bytes); //if (bytesRec != 0) // Console.WriteLine("Receive some bytes"); header += System.Text.Encoding.UTF8.GetString(bytes, 0, bytesRec); for (int i = 0; i < bytesRec; i++) { ResponseBytesList.Add(bytes[i]); } if (header.IndexOf("\r\n\r\n") > -1 || header.IndexOf("\n\n") > -1) { //Console.WriteLine("Blank line found"); break; } } Console.WriteLine(header); // Break up the headers string[] headers = header.Split(new char[] { '\n' }); // Get the HTTP payload next string data = header; int contentLength = GetContentLength(headers); //Console.WriteLine(utf8.GetString(ResponseBytes, 0, ResponseBytes.Length)); 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); 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 = ResponseBytesList.ToArray(); clientSock.Send(ResponseBytes); } catch (System.Exception) { } //Console.WriteLine("data \n" + data); s.Shutdown(SocketShutdown.Both); s.Close(); }catch (Exception ex) { //Console.WriteLine(ex.ToString()); } }// DoRequest 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; 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; set; } // Response public string Header { get; private set; } public Socket clientSock { get; private set; } public byte[] RequestBytes { get; private set; } public byte[] ResponseBytes { get; private set; } } // class RequestHandler }// namespace LocalhostProxy