一直觉得网站www.studyez.com 处理静态文件不怎么快,就想能不能把这些静态文件单独放在另外一台服务器(StaticFileServer)上面。让主服务器只处理.aspx文件即可。StaticFileServer只负责输出静态文件,减轻主服务器的压力。远景的想法是把它用C/C++改写。
不过,发现用C/C++哪是相当的麻烦,而且也没有必要。反正就是自己用用。先搭个架子先吧。
对于以后的GET请求的分析,稍后在发上来。网上找的一些基上都是把接收到byte[]转化成字符串然后来分析,
个人觉得这种做法效率不怎么好。不过目前也没想到什么好法子。特别对于POST请求的分析。
下面涉及到异步回调《AsyncCallback》,Socket 等东西。好记性不如烂笔头,还是记下先吧。
下面是源代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Net.Cache;
using System.IO;
namespace WinSocket
{
public class HttpSocket
{
static System.Threading.AutoResetEvent a = new System.Threading.AutoResetEvent(true);
static void Main(string[] args)
{
IPHostEntry en = Dns.GetHostEntry("127.0.0.1");
IPAddress ipAddr = en.AddressList[0];
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Bind(new IPEndPoint(ipAddr, 10000));
server.Listen(1000);
try
{
while (true)
{
a.Reset();
Console.WriteLine("Waiting for a connection...");
server.BeginAccept(new AsyncCallback(AcceptReceiveDataCallback), server);
//int receivedDataSize = 1024;
//server.BeginAccept(receivedDataSize, new AsyncCallback(AcceptReceiveDataCallback), server);
// Wait until a connection is made and processed before continuing.
a.WaitOne();
}
}
finally
{
server.Shutdown(SocketShutdown.Both);
server.Close();
}
}
static void AcceptReceiveDataCallback(IAsyncResult ar)
{
// Get the socket that handles the client request.
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
//byte[] Buffer;
//int bytesTransferred;
//Socket handler = listener.EndAccept(out Buffer, out bytesTransferred, ar);
a.Set();
//string stringTransferred = Encoding.ASCII.GetString(Buffer, 0, bytesTransferred);
//Console.WriteLine(stringTransferred);
//Console.WriteLine("Size of data transferred is {0}", bytesTransferred);
ReceiveStateObject state = new ReceiveStateObject(handler, 1024);
handler.BeginReceive(state.Buffer, 0, state.BufferSize, SocketFlags.None, new AsyncCallback(ReadCallback), state);
}
static void ReadCallback(IAsyncResult ar)
{
ReceiveStateObject state = (ReceiveStateObject)ar.AsyncState;
Socket handler = state.WorkerSocket;
int read = handler.EndReceive(ar);
if (read > 0 && read ==state.BufferSize )
{
//继续读取
handler.BeginReceive(state.Buffer, 0, state.BufferSize, SocketFlags.None, new AsyncCallback(ReadCallback), state);
}
else
{
//处理结束
//读取结束
StringBuilder _sb = new StringBuilder();
FileInfo fi = new FileInfo(@"H:/HttpWebServer/index.html");
_sb.AppendLine("HTTP/1.0 200 OK");
_sb.AppendLine("MIME-version:1.0");
_sb.AppendLine("Content-type:text/html");
_sb.AppendLine("Content-length:" + fi.Length.ToString());
_sb.AppendLine();
byte[] c = System.Text.Encoding.Default.GetBytes(_sb.ToString());
handler.BeginSend(c, 0, c.Length, SocketFlags.None, new AsyncCallback(SendCallback), new ResponseStateObject(handler, c.Length));
}
}
static void SendCallback(IAsyncResult ar)
{
ResponseStateObject res = (ResponseStateObject)ar.AsyncState;
Socket handler = res.WorkerSocket;
int c = handler.EndSend(ar);
if (c != res.Len)
{
Console.WriteLine("数据尚未正确发送出去!");
}
else
{
handler.BeginSendFile(@"H:/HttpWebServer/index.html", new AsyncCallback(SendFileCallback), new SendFileStateObject(handler));
}
}
static void SendFileCallback(IAsyncResult ar)
{
SendFileStateObject st = (SendFileStateObject)ar.AsyncState;
st.WorkerSocket.EndSendFile(ar);
st.WorkerSocket.Shutdown(SocketShutdown.Both);
st.WorkerSocket.Close();
}
class ReceiveStateObject
{
private Byte[] _buffer;
private int _size;
private Socket _s;
private StringBuilder sb;
public ReceiveStateObject(Socket woker, int bufferSize)
{
_s = woker;
_size = bufferSize;
_buffer = new byte[bufferSize];
sb = new StringBuilder();
}
public Socket WorkerSocket
{
get { return _s; }
}
public int BufferSize
{
get { return _size; }
}
public Byte[] Buffer
{
get { return _buffer; }
}
public StringBuilder ContentContainer
{
get { return sb; }
}
}
class ResponseStateObject
{
public int Len;
public Socket WorkerSocket;
public ResponseStateObject(Socket s, int sendLen)
{
WorkerSocket = s;
Len = sendLen;
}
}
class SendStateObject
{
private Byte[] _buffer;
private Socket _s;
public SendStateObject(Socket socket, byte[] buffer)
{
_s = socket;
_buffer = buffer;
}
public Socket WorkerSocket
{
get { return _s; }
}
public Byte[] Buffer
{
get { return _buffer; }
}
}
class SendFileStateObject
{
public Socket WorkerSocket;
public SendFileStateObject(Socket s)
{
WorkerSocket = s;
}
}
}
}