初衷
随着个人的需求在日常使用中需要对资源实现远程访问,现在服务器的资源,也需要将一些本地的资源上传到服务器,基于这个简单的需求,于是想对web服务器做一些了解,通过查找一些资源,对web服务端有了一个初步的了解,在此特别感谢IT周见智,做了我很好的领路人,由于我还是个雏,所以在此多为自己记录笔记,如果有大佬不吝指教,亦十分欢迎.
代码部分
使用socket模拟
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace myFirstServer
{
public class MyWebServer
{
private TcpListener myListener;
private int port = 8080; // 服务器端口
public MyWebServer()
{
try
{
// 开始监听端口
myListener = new TcpListener(port);
myListener.Start();
Console.WriteLine("服务器开启");
// 启动监听进程 StratListen
Thread th = new Thread(new ThreadStart(StartListen));
th.Start();
}
catch(Exception e)
{
Console.WriteLine("监听端口发生错误" + e.ToString());
}
}
public void SendHeader(string sHttpVersion,string sMIMEHeader,int iToBytes,string sStatusCode,ref Socket mySocket)
{
string sBuffer = "";
if(sMIMEHeader.Length == 0)
{
sMIMEHeader = "text/html";
}
sBuffer = sBuffer + sHttpVersion + sStatusCode + "\r\n";
sBuffer = sBuffer + "Server:cx1193719-b\r\n";
sBuffer = sBuffer + "Content-type:" + sMIMEHeader + "\r\n";
sBuffer = sBuffer + "Accept-Ranges:bytes\r\n";
sBuffer = sBuffer + "Content-Length:" + iToBytes + "\r\n\r\n";
Byte[] bSendData = Encoding.ASCII.GetBytes(sBuffer);
SendToBrowserByte(bSendData, ref mySocket);
Console.WriteLine("当前字节总数:" + iToBytes.ToString());
}
public void SendToBrowserString(string sData, ref Socket mySocket)
{
SendToBrowserByte(Encoding.ASCII.GetBytes(sData), ref mySocket);
}
public void SendToBrowserByte(Byte[] bSendData,ref Socket mySocket)
{
int numBytes = 0;
try
{
if(mySocket.Connected)
{
if((numBytes = mySocket.Send(bSendData,bSendData.Length,0)) == -1)
{
Console.WriteLine("Socket错误,无法发送数据");
}
else
{
Console.WriteLine("当前发送字节{0}", numBytes);
}
}
else
{
Console.WriteLine("链接失败");
}
}
catch(Exception e)
{
Console.WriteLine("发生错误:{0}", e);
}
}
public static void Main()
{
MyWebServer mws = new MyWebServer();
}
public void StartListen()
{
int iStartPos = 0;
String sRequest;
String sDirName;
String sRequestedFile;
String sErrorMessage;
String sLocalDir;
String sMyWebServerRoot = "G:/WebServer/ServerRootTest";
String sPhysicalFilePath = "";
String sFormattedMessage = "";
String sResponse = "";
while(true)
{
// 接受新连接
Socket mySocket = myListener.AcceptSocket();
Console.WriteLine("Socket Type" + mySocket.SocketType);
if(mySocket.Connected)
{
Console.WriteLine("\n客户端连接成功\n===================\n客户端IP{0}\n", mySocket.RemoteEndPoint);
Byte[] bReceive = new byte[1024];
int i = mySocket.Receive(bReceive, bReceive.Length, 0);
// 转换为字符串类型
string sBuffer = Encoding.ASCII.GetString(bReceive);
// 处理GET请求
if(sBuffer.Substring(0,3)!= "GET")
{
Console.WriteLine("GET请求");
mySocket.Close();
return;
}
// 查找 HTTP 位置
iStartPos = sBuffer.IndexOf("HTTP", 1);
string sHttpVersion = sBuffer.Substring(iStartPos, 8);
// 获取请求类型 文件目录 文件名
sRequest = sBuffer.Substring(0, iStartPos - 1);
sRequest.Replace("//", "/");
// 如果结尾不是文件名 也不是以"/"结尾加上"/"
if((sRequest.IndexOf(".") < 1) && (!sRequest.EndsWith("/")))
{
sRequest = sRequest + "/";
}
// 请求文件名
iStartPos = sRequest.LastIndexOf("/") + 1;
sRequestedFile = sRequest.Substring(iStartPos);
// 请求目录
sDirName = sRequest.Substring(sRequest.IndexOf("/"), sRequest.LastIndexOf("/") - 3);
// 虚拟目录物理地址
sLocalDir = sMyWebServerRoot;
Console.WriteLine("请求文件目录:" + sLocalDir);
// 虚拟目录物理地址无效
if (sLocalDir.Length == 0)
{
sErrorMessage = "请求的文件路径不存在";
SendHeader(sHttpVersion, "", sErrorMessage.Length, "404 Not Found", ref mySocket);
SendToBrowserString(sErrorMessage, ref mySocket);
mySocket.Close();
continue;
}
// 请求文件名无效
if(sRequestedFile.Length == 0)
{
sRequestedFile = "index.html";
}
// 获取请求类型
String sMimeType = "text/html";
// 请求文件位置
sPhysicalFilePath = sLocalDir + sRequestedFile;
Console.WriteLine("请求文件位置:" + sPhysicalFilePath);
// 如果请求文件不存在
if(!File.Exists(sPhysicalFilePath))
{
sErrorMessage = "请求的文件不存在";
SendHeader(sHttpVersion, "", sErrorMessage.Length, "404 Not Found", ref mySocket);
SendToBrowserString(sErrorMessage, ref mySocket);
Console.WriteLine(sFormattedMessage);
}
else
{
int iToBytes = 0;
sResponse = "";
FileStream fs = new FileStream(sPhysicalFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryReader reader = new BinaryReader(fs);
byte[] bytes = new byte[fs.Length];
int read;
while ((read = reader.Read(bytes, 0, bytes.Length)) != 0)
{
sResponse = sResponse + Encoding.ASCII.GetString(bytes, 0, read);
iToBytes = iToBytes + read;
}
reader.Close();
fs.Close();
SendHeader(sHttpVersion, sMimeType, iToBytes, "200 OK", ref mySocket);
SendToBrowserByte(bytes, ref mySocket);
}
mySocket.Close();
}
}
}
}
}
ps
在处理的时候没有对请求的路径做分析,以上只能粗略的访问到服务器根目录下的文件,对于其下的路径均为做判断.不可以直接拿来使用,此处只是为了留个印痕,方便自己遗忘时可以查看
网友评论