DanmerRUS
Время...
Наткнулся тут на код HTTP-прокси.
Проблемы:

1) Один поток (Хотя, очевидно, программист хотел параллелить, но не довёл, скорее всего, из-за неумения синхронизировать процессы)
2) Перекодировка массива байт через ASCII в строку (Очевидно, что данные могут шифроваться, и в шифре может встречаться символ '\0', что сильно скажется не переводе, а точнее перевод будет остановлен на этом месте, что приведёт к ошибке передачи страницы клиенту)

А потому я его переписал и исправил. Проблем еще много, хорошо было бы, если бы написали сюда о них 0_о

Почему-то у меня не получается совладать с тегом [ CODE ] тут 0_о

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;

namespace MyProxyServer
{
class MyProxyServer
{
const int Proxyport = 5678;
readonly Socket _clientSocket;
readonly Byte[] _readbyte = new byte[4096];
Byte[] _buffermessage;
readonly Byte[] _receivebuffer = new Byte[4096];
int _iCountFiles = 1;
private const string SFileName = "cache\\myproxyserver_data_";
private const string SFileExt = ".dat";
string _sFullFileName = "";
long _count;
private const string LogFileName = "cache\\MyProxyLogFile.txt";
private readonly Semaphore _sem1 = new Semaphore(1, 1);

public MyProxyServer(Socket socket)
{
_clientSocket = socket;
}

//Thread func
public void RunProxy()
{
string sRequest2LogFile;
string sRequest2LogFileOld = "";

//Client socket, the client is using this program as a proxy server
int ireadbytes = _clientSocket.Receive(_readbyte, 4096, 0);
string stmpstring = Encoding.ASCII.GetString(_readbyte);
string sMessage = stmpstring;

//Get the request from the message
if (sMessage.Contains("HTTP";))
sRequest2LogFile = sMessage.Substring(0, sMessage.IndexOf("HTTP", 10) - 1);
else
{
return;
}
//Check if we have already this request on the cache
string sDataFileToSend = WebRequestExists(sRequest2LogFile);
if (sDataFileToSend != "";)
{
//We have a file to send instead of get the webpage
var fileDataFromDisk = new FileStream(sDataFileToSend, FileMode.OpenOrCreate);
_buffermessage = new Byte[fileDataFromDisk.Length];

int ireadbytesfromfile = fileDataFromDisk.Read(_buffermessage, 0, _buffermessage.Length);
while (ireadbytesfromfile != 0)
{
_clientSocket.Send(_buffermessage, ireadbytesfromfile, 0);
ireadbytesfromfile = fileDataFromDisk.Read(_buffermessage, 0, _buffermessage.Length);
}
_clientSocket.Close();
}
else
{
while (ireadbytes != 0)
{

long total = 0;
//Parse the string to find the host and web page
int iHostNameStart = sMessage.IndexOf("";;);
int iHostNameEnd = sMessage.IndexOf(" ", 7 + iHostNameStart);
int iHostNameEndFirstSlash = sMessage.IndexOf("//";);
iHostNameEndFirstSlash = sMessage.IndexOf("/", iHostNameEndFirstSlash + 3);

if (sMessage.Substring(0, 7) != "CONNECT";)
{
var swebhost = sMessage.Substring(iHostNameStart + 7, iHostNameEndFirstSlash - iHostNameStart - 7);

Console.WriteLine("Connecting to the page {0}",
sMessage.Substring(iHostNameStart, iHostNameEnd - iHostNameStart));
Console.WriteLine("Connection from {0} the client", _clientSocket.RemoteEndPoint);
var ipHost = Dns.GetHostEntry(swebhost);
var ipAddressList = ipHost.AddressList;
var ipEndPoint = new IPEndPoint(ipAddressList[0], 80);
//This is a socket to the real webserver with the webpage
var websocket = new Socket
(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
websocket.Connect(ipEndPoint);

if (websocket.Connected)
{
Console.WriteLine("Socket connected OK to webserver";);
}
//sMessage is the request from the client
string hostmessage = sMessage;
var getmessage = Encoding.ASCII.GetBytes(hostmessage);
//Send the message package to the webserver
websocket.Send(getmessage, getmessage.Length, 0);
//Receive data from the webserver
var ireceivedbyte = websocket.Receive(_receivebuffer, _receivebuffer.Length, 0);
var byteLst = new List();
byteLst.AddRange(_receivebuffer);

Console.WriteLine("Received from webserver socket {0} bytes", +ireceivedbyte);
string spage = Encoding.ASCII.GetString(_receivebuffer, 0, ireceivedbyte);

while (ireceivedbyte > 0)
{
ireceivedbyte = websocket.Receive(_receivebuffer, _receivebuffer.Length, 0);
spage = spage + Encoding.ASCII.GetString(_receivebuffer, 0, ireceivedbyte);
byteLst.AddRange(_receivebuffer);
Console.WriteLine("Received from webserver socket {0} bytes", +ireceivedbyte);
}
//Save to file!!!
if (sRequest2LogFile != sRequest2LogFileOld)
{
_sFullFileName = SFileName + _iCountFiles.ToString() + SFileExt;
while (File.Exists(_sFullFileName))
{
_iCountFiles++;
_sFullFileName = SFileName + _iCountFiles.ToString() + SFileExt;
}

var file1 = new FileStream(_sFullFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
sRequest2LogFile = sMessage.Substring(0, sMessage.IndexOf("HTTP", 10) - 1);
var sTmpStr = "REQUEST:" + sRequest2LogFile + "," + "FILE:" + file1.Name + "\r\n";
var encoding = new ASCIIEncoding();
var byte2Logfile = encoding.GetBytes(sTmpStr);

_sem1.WaitOne();
lock (LogFileName)
{
var logFileStream = new FileStream(LogFileName, FileMode.Append);
logFileStream.Write(byte2Logfile, 0, byte2Logfile.Length);
logFileStream.Close();
logFileStream.Dispose();
}
_sem1.Release();

sRequest2LogFileOld = sRequest2LogFile;

//Read into memory stream
var memStream = new MemoryStream(byteLst.ToArray());
memStream.WriteTo(file1);
//file1.Write(receivebuffer, 0, receivebuffer.Length);
_count = memStream.Length;

total += _count;
Console.WriteLine(" wrote {0} total bytes", total);
}

//Now we send the message back to the orginal client who was asking for some webpage
_buffermessage = new Byte[spage.Length + 1];
int ilength = Encoding.ASCII.GetBytes(spage, 0, spage.Length, _buffermessage, 0);
_clientSocket.Send(byteLst.ToArray(), ilength, 0);
websocket.Shutdown(SocketShutdown.Both);
websocket.Close();
try
{
ireadbytes = _clientSocket.Receive(_readbyte, 4096, 0);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
}

//Return path of exist resource, if resource is not exist, return ""
public string WebRequestExists(string sRequest)
{
var sDataFileName = "";

if (File.Exists(LogFileName))
{
_sem1.WaitOne();
lock (LogFileName)
{
var logFileCheck = new FileStream(LogFileName, FileMode.Open);
var inStream = new StreamReader(logFileCheck);
var sLine = inStream.ReadLine();
while (sLine != null)
{
Console.WriteLine(sLine);
int iStartOffFileName = sLine.IndexOf("FILE:", 15);

var sLocalRequest = sLine.Substring(8, iStartOffFileName - 9);

//We already have the reqeust
if (sLocalRequest == sRequest)
{
sDataFileName = sLine.Substring
(iStartOffFileName + 5, sLine.Length - iStartOffFileName - 5);
}
sLine = inStream.ReadLine();
}

logFileCheck.Close();
logFileCheck.Dispose();
}
_sem1.Release();
}
return sDataFileName;
}

public static int Main(string[] args)
{
var tcplistener = new TcpListener(IPAddress.Any, Proxyport);
Console.WriteLine("Proxy server is listening to port {0}", +Proxyport);
tcplistener.Start();
while (true)
{
var socket = tcplistener.AcceptSocket();
var myproxyserver = new MyProxyServer(socket);
var thread = new Thread(myproxyserver.RunProxy);
thread.Start();
}
}
}
}