TCP/IP协议学习(四) 基于C# Socket的Web服务器---静态资源处理

目录

1. C# Socket通讯

2. HTTP 解析引擎

3. 资源读取和返回

4. 服务器测试和代码下载

  Web服务器是Web资源的宿主,它需要处理用户端浏览器的请求,并指定对应的Web资源返回给用户,这些资源不仅包括HTML文件,JS脚本,JPG图片等,还包括由软件生成的动态内容。为了满足上述需求,一个完整的Web服务器工作流程:

  1) 服务器获得浏览器通过TCP/IP连接向服务器发送的http请求数据包。

  2) HTTP请求经过Web服务器的HTTP解析引擎分析得出请求方法、资源地址等信息,然后开始处理。

  3) 对于静态请求,则在服务器上查询请求url路径下文件,并返回(如果未找到则返回404 No Found)。

  4) 涉及动态请求,如CGI, AJAX, ASP等,则根据http方法,采取不同处理。

  aaarticlea/png;base64,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" alt="" />

  Web服务器的核心由C# Socket通讯,http解析引擎,静态资源文件查找,动态数据接收和发送4部分组成,本节因为个人编写进度原因主要实现前3个部分(即能够查询静态资源的Web服务器),动态数据处理因为涉及的处理方式CGI,AJAX,ASP的方法不同,后续完成后在总结相关知识。

1. C# Socket通讯 

  C# Socket通过对TCP/IP协议进行封装,用于实现满足TCP通讯的API。在B/S架构中,服务器端的处理和C/S连接基本相同,主要工作包含:创建Socket套接字,监听连接,建立连接,获得请求,处理并返回数据,关闭连接等。

  程序入口函数,采用轮询方式实现对客户端请求的监听。

          //创建监听线程
Thread Listen_thread = new Thread(socket_listen);
Listen_thread.IsBackground = false;
Listen_thread.Start();

  监听线程,创建Socket套接字,绑定并监听指定端口,等待连接建立,连接建立后,考虑到网页请求高并发的特性,采用另开线程的方式来处理建立的连接,从而实现并发服务器模式。

            Socket server_socket = null;

            //监听的IP地址和端口 作为服务器,绑定的只能是本机Ip地址或者环回地址(不能与系统其它进程端口冲突)
//如果绑定为本节IP地址,局域网下其它设备可以通过http://host:port来访问当前服务器
string host = "127.0.0.1";
int port = ; IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port); //新建Socket套接字,绑定在指定的端口并开始监听
server_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server_socket.Bind(ipe);
server_socket.Listen();
Console.WriteLine("Server Binding at " + host + ":" + port.ToString() +"...");
Console.WriteLine("Wait for connect...."); while (true)
{
Socket CurrentSocket; //三次握手成功,新建一个连接
CurrentSocket = server_socket.Accept(); Console.WriteLine("New TCP Socket Create..."); //单开一个线程用来处理服务器收发, 并发服务器模式
ParameterizedThreadStart tStart = new ParameterizedThreadStart(socket_process);
Thread process_thread = new Thread(tStart);
process_thread.IsBackground = false;
process_thread.Start(CurrentSocket);
}

  连接处理,socket通讯处理主要负责接收连接产生的数据,并将http引擎处理后数据提交给客户端浏览器。

          Socket CurrentSocket = (Socket)obj;
try
{
string recvStr = "";
byte[] recvBytes = new byte[];
int length; //获得当前Socket连接传输的数据,并转换为ASCII码格式
length = CurrentSocket.Receive(recvBytes, recvBytes.Length, );
recvStr = Encoding.ASCII.GetString(recvBytes, , length); //http引擎处理,返回获得数据
byte[] bs = http_engine(recvStr, length); //通过socket发送引擎处理后数据
CurrentSocket.Send(bs, bs.Length, );
Console.WriteLine("File Send Finish, Socket Close....\r\n"); //关闭socket连接
CurrentSocket.Close();
}
catch (Exception exception)
{
Console.WriteLine(exception);
CurrentSocket.Close();
}

  C# Socket通讯架构的实现和C/S结构没有什么区别,如果了解过Socket可以轻松实现上述socket通讯架构。 不过下面这部分将讲述Web服务器的实现核心--http解析引擎,这也是B/S架构和C/S架构中服务器端最大的区别。

2. http解析引擎

  Web服务器主要实现对浏览器请求数据包的处理,并返回指定的http资源或者数据,这些都是由http解析引擎实现,在写http解析引擎之前,我们要知晓接收到的数据才能进行后续的处理,这里提供通过WireShark抓取的http请求包:

TCP/IP协议学习(四) 基于C# Socket的Web服务器---静态资源处理

  虽然HTTP请求包的内容很多,但因为目前实现的功能较少,所以关注的只有http报文起始行就可以,而首部字段可以直接丢弃不处理,后续如果使用认证机制,如白名单,黑名单过滤,帐号/密码保护,资源权限管理等,首部仍然要处理。

  对于http报文起始行, 内部以space隔开,并以'\r\n'作为结尾与首部隔开。其中GET:HTTP方法, '/' :资源路径url, HTTP/1.1:协议版本,参照http权威指南的内容,  HTTP协议的常见方法有GET, PUT, DELETE, POST, HEAD这5种,本节中的静态服务器主要涉及到GET方法。了解了需要如何解析HTTP请求报文后,我们先定义一个HTTP报文解析结构,用于存储到解析的信息。

        public class HTTPPrase
{
//http方法
public string http_method; //http资源
public string url; //http版本号
public string version; //url解析的请求网页类型
public string type;
};

  下面我们就要开始利用C#提供的String方法来截取http报文来实现上述结构体内参数的初始化。

            int pos;

           //根据\r\n截断,获取http报文首部并转换为小写,方便后续处理
//Get / HTTP/1.1/r/n
pos = str.IndexOf("\r\n");
string str_head = str.Substring(, pos);
str_head = str_head.ToLower(); //根据' '来截断起始行,并赋值给对应参数
string[] arr = Regex.Split(str_head, @"\s+");
HTTPServer.HTTPPrase http_head = new HTTPServer.HTTPPrase();
http_head.http_method = arr[]; // "Get"
http_head.url = arr[]; // "/"
http_head.version = arr[]; // "HTTP/1.1" //判断是否有通过ajax要求获得或者提交的动态数据
http_head.ajax_status = str_head.IndexOf(".ajax") != - ? true : false; byte[] bs = http_head.ajax_status == true ? ajax_process(http_head, str) : static_process(http_head, str); return bs;

  下面就可以把数据提交给后端接口,进行处理。因为动态网页处理需要网页端和后端相互的配合,工作量较大,因此本节主要阐述静态网页请求的实现。

3. 资源读取和返回

  局域网Web请求一般是通过ip+port的模式直接访问服务器端,所以第一个接收到的请求的url为‘/',这时我们需要将它映射到服务端定位的访问主页,目前设置为index.html,对于其它请求,url的值一般是'/xxx/xxx.js", '/xxx/xxx.jpg"等,而在服务器中读取时我们需要定义绝对地址,所以还要在前面添加资源存储的根地址,目前将程序当前所在文件夹+html作为资源的根地址,而且操作系统存储的数据路径为\xxx\xxx.js,所以对于请求中url数据还要替换为'\\'(为了保证转义符能够转变为路径符,需要用'\\'表示实际的'\'),此外为了后续的http响应报文中返回正确的Content-Type字段,还有截取'.'后字段,来获取请求文件的类型。

              //获得当前程序所在的文件夹
string url_str = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
if (string.Compare(head.url, "/") == )
{
//对于首个请求127.0.0.1:3000/ 返回index.html
url_str += "html\\index.html";
head.type = "html";
}
else
{
//其它请求 如/spring.js 替换为 ...\html\spring.js便于C#查询文件路径
url_str =url_str + "html\\" + head.url.Substring();
url_str = url_str.Replace('/', '\\');
int pos = url_str.IndexOf('.'); //获得当前请求的网页类型
head.type = url_str.Substring(pos + );
}

  到此为止,完成了整个http解析的过程,包括http方法, url资源地址获得并转换为windows系统路径,协议版本获得三个部分。对于静态网页请求,后续就比较简单,查询系统路径下资源,通过文件流打开,并以字符流的形式放置在内存中,作为http响应报文的正文部分。

             //以文件流的方式打开指定路径内文件
using (FileStream fs = new FileStream(url_str, FileMode.Open, FileAccess.Read))
{
//StreamReader temp = new StreamReader(fs, Encoding.Default);
int fslen = (int)fs.Length;
byte[] fbyte = new byte[fslen];
int r = fs.Read(fbyte, , fslen);
fs.Close(); //......
}

文件打开成功后,我们就要生成http响应报文了,http响应报文和请求报文相同,也由三部分构成。

  状态码:主要为客户端提供一种理解事务处理结果的便捷方式。主要实现的有:

  HTTP/1.1 200 OK 请求没有问题,实体的主体部分包含请求的资源

HTTP/1.1 400 Bad Request 通知客户端它发送了一个错误的请求

  HTTP/1.1 401 Unauthorized 与适当的首部一同返回,通知客户端进行相应的认证

HTTP/1.1 404 No Found 说明服务器无法找到请求的URL

 响应首部:为客户端提供额外的关于服务器的消息,本项目中实现比较简单:

  Content-type:CurrentType\r\n

  Server:C# Web\r\n

  Content-Length:CurrentLength\r\n

  Connection: close

 其中Contenet-type需要根据我们上文获得的type类型来替换,这里阐述常见的替换规则。

TCP/IP协议学习(四) 基于C# Socket的Web服务器---静态资源处理

Content-Length字段是http响应报文正文的长度,即我们获得资源的总长度(上文中fslen), 最后将状态码,响应首部和正文数据整合在一起通过socket发送到客户端,就实现了静态服务器的全部过程。

                            string HTTP_Current_Head = HTTPServer.HTTP_OK_Head.Replace("CurrentLength", Convert.ToString(fslen));

                            //根据不同url需要返回不同的首部类型 具体对比详见http://tool.oschina.net/commons
   switch (head.type)
{
case "jpg":
HTTP_Current_Head = HTTP_Current_Head.Replace("CurrentType", "application/x-jpg");
break;
case "png":
HTTP_Current_Head = HTTP_Current_Head.Replace("CurrentType", "image/png");
break;
case "html":
HTTP_Current_Head = HTTP_Current_Head.Replace("CurrentType", "text/html");
break;
case "gif":
HTTP_Current_Head = HTTP_Current_Head.Replace("CurrentType", "image/gif");
break;
case "js":
HTTP_Current_Head = HTTP_Current_Head.Replace("CurrentType", "application/x-javascript");
break;
case "asp":
HTTP_Current_Head = HTTP_Current_Head.Replace("CurrentType", "text/asp");
break;
default:
HTTP_Current_Head = HTTP_Current_Head.Replace("CurrentType", "text/html");
break;
} send_str = HTTPServer.HTTP_OK_Start + HTTP_Current_Head;
byte[] head_byte = new byte[send_str.Length];
head_byte = Encoding.UTF8.GetBytes(send_str); //字符串流合并,生成发送文件
//之前采用的是byte[]->string, string合并, string->byte[],这种方法读取图片乱码
//因此修改为,string合并, string->byte[], byte[]合并方式,读取图片成功
byte[] send_byte = new byte[send_str.Length + fbyte.Length];
Buffer.BlockCopy(head_byte, , send_byte, , head_byte.Length);
Buffer.BlockCopy(fbyte, , send_byte, head_byte.Length * sizeof(byte), fbyte.Length); Console.WriteLine("File Send....");
return send_byte;

4. 服务器测试和代码下载

  到现在为止,一个简单的静态web服务器就实现了,将希望访问的资源文件放入当前程序文件夹/html/下, 并将首页定义为index.html, 点开服务器程序,浏览器中输入http://127.0.0.1:3000, 就可以查看返回的网页。

TCP/IP协议学习(四) 基于C# Socket的Web服务器---静态资源处理

具体程序参考:Web服务器下载

 

上一篇:python面对对象编程----1:BlackJack(21点)


下一篇:第一篇 先用socket模拟web服务器