C#实现多线程的Web代理服务器实例
本文实例讲述了C#实现多线程的Web代理服务器。分享给大家供大家参考。具体如下:
/**
Proxy.cs:
C#ProgrammingTips&Techniques
byCharlesWright,KrisJamsa
Publisher:Osborne/McGraw-Hill(December28,2001)
ISBN:0072193794
*/
//Proxy.cs--Implementsamulti-threadedWebproxyserver
//
//Compilethisprogramwiththefollowingcommandline:
//C:>cscProxy.cs
usingSystem;
usingSystem.Net;
usingSystem.Net.Sockets;
usingSystem.Text;
usingSystem.IO;
usingSystem.Threading;
namespacensProxyServer
{
publicclassProxyServer
{
staticpublicvoidMain(string[]args)
{
intPort=3125;
if(args.Length>0)
{
try
{
Port=Convert.ToInt32(args[0]);
}
catch
{
Console.WriteLine("Pleaseenteraportnumber.");
return;
}
}
try
{
//Createalistenerfortheproxyport
TcpListenersockServer=newTcpListener(Port);
sockServer.Start();
while(true)
{
//Acceptconnectionsontheproxyport.
Socketsocket=sockServer.AcceptSocket();
//WhenAcceptSocketreturns,itmeansthereisaconnection.Create
//aninstanceoftheproxyserverclassandstartathreadrunning.
clsProxyConnectionproxy=newclsProxyConnection(socket);
Threadthrd=newThread(newThreadStart(proxy.Run));
thrd.Start();
//Whilethethreadisrunning,themainprogramthreadwilllooparound
//andlistenforthenextconnectionrequest.
}
}
catch(IOExceptione)
{
Console.WriteLine(e.Message);
}
}
}
classclsProxyConnection
{
publicclsProxyConnection(SocketsockClient)
{
m_sockClient=sockClient;
}
Socketm_sockClient;//,m_sockServer;
Byte[]readBuf=newByte[1024];
Byte[]buffer=null;
EncodingASCII=Encoding.ASCII;
publicvoidRun()
{
stringstrFromClient="";
try
{
//Readtheincomingtextonthesocket/
intbytes=ReadMessage(m_sockClient,
readBuf,refstrFromClient);
//Ifit'sempty,it'sanerror,sojustreturn.
//Thiswilltermiatethethread.
if(bytes==0)
return;
//GettheURLfortheconnection.TheclientbrowsersendsaGETcommand
//followedbyaspace,thentheURL,thenandidentiferfortheHTTPversion.
//ExtracttheURLasthestringbetweeenthespaces.
intindex1=strFromClient.IndexOf('');
intindex2=strFromClient.IndexOf('',index1+1);
stringstrClientConnection=
strFromClient.Substring(index1+1,index2-index1);
if((index1<0)||(index2<0))
{
throw(newIOException());
}
//Writeamesssagethatweareconnecting.
Console.WriteLine("ConnectingtoSite"+
strClientConnection);
Console.WriteLine("Connectionfrom"+
m_sockClient.RemoteEndPoint);
//CreateaWebRequestobject.
WebRequestreq=(WebRequest)WebRequest.Create
(strClientConnection);
//GettheresponsefromtheWebsite.
WebResponseresponse=req.GetResponse();
intBytesRead=0;
Byte[]Buffer=newByte[32];
intBytesSent=0;
//Createaresponsestreamobject.
StreamResponseStream=response.GetResponseStream();
//Readtheresponseintoabuffer.
BytesRead=ResponseStream.Read(Buffer,0,32);
StringBuilderstrResponse=newStringBuilder("");
while(BytesRead!=0)
{
//Passtheresponsebacktotheclient
strResponse.Append(Encoding.ASCII.GetString(Buffer,
0,BytesRead));
m_sockClient.Send(Buffer,BytesRead,0);
BytesSent+=BytesRead;
//Readthenextpartoftheresponse
BytesRead=ResponseStream.Read(Buffer,0,32);
}
}
catch(FileNotFoundExceptione)
{
SendErrorPage(404,"FileNotFound",e.Message);
}
catch(IOExceptione)
{
SendErrorPage(503,"Servicenotavailable",e.Message);
}
catch(Exceptione)
{
SendErrorPage(404,"FileNotFound",e.Message);
Console.WriteLine(e.StackTrace);
Console.WriteLine(e.Message);
}
finally
{
//Disconnectandclosethesocket.
if(m_sockClient!=null)
{
if(m_sockClient.Connected)
{
m_sockClient.Close();
}
}
}
//Returningfromthismethodwillterminatethethread.
}
//Writeanerrorresponsetotheclient.
voidSendErrorPage(intstatus,stringstrReason,stringstrText)
{
SendMessage(m_sockClient,"HTTP/1.0"+""+
status+""+strReason+"\r\n");
SendMessage(m_sockClient,"Content-Type:text/plain"+"\r\n");
SendMessage(m_sockClient,"Proxy-Connection:close"+"\r\n");
SendMessage(m_sockClient,"\r\n");
SendMessage(m_sockClient,status+""+strReason);
SendMessage(m_sockClient,strText);
}
//Sendastringtoasocket.
voidSendMessage(Socketsock,stringstrMessage)
{
buffer=newByte[strMessage.Length+1];
intlen=ASCII.GetBytes(strMessage.ToCharArray(),
0,strMessage.Length,buffer,0);
sock.Send(buffer,len,0);
}
//Readastringfromasocket.
intReadMessage(Socketsock,byte[]buf,refstringstrMessage)
{
intiBytes=sock.Receive(buf,1024,0);
strMessage=Encoding.ASCII.GetString(buf);
return(iBytes);
}
}
}
希望本文所述对大家的C#程序设计有所帮助。