web服务端

2018-06-22  本文已影响5人  爱喝粥的西瓜

初衷

随着个人的需求在日常使用中需要对资源实现远程访问,现在服务器的资源,也需要将一些本地的资源上传到服务器,基于这个简单的需求,于是想对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
在处理的时候没有对请求的路径做分析,以上只能粗略的访问到服务器根目录下的文件,对于其下的路径均为做判断.不可以直接拿来使用,此处只是为了留个印痕,方便自己遗忘时可以查看

上一篇下一篇

猜你喜欢

热点阅读