目录

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请求包:

  虽然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类型来替换,这里阐述常见的替换规则。

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, 就可以查看返回的网页。

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

 

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

  1. TCP/IP协议学习(七) 基于C# Socket的Web服务器---动态通讯实现

    目录 (1).基于Ajax的前端实现 (2).Web服务器后端处理 一个完整的web服务器,不仅需要满足用户端对于图片.文档等资源的需求:还能够对于用户端的动态请求,返回指定程序生成的数据.支持动态请 ...

  2. TCP/IP协议学习(五) 基于C# Socket的C/S模型

    TCP/IP协议作为现代网络通讯的基石,内容包罗万象,直接去理解理论是比较困难的:然而通过实践先理解网络通讯的理解,在反过来理解学习TCP/IP协议栈就相对简单很多.C#通过提供的Socket API ...

  3. TCP/IP协议学习(四) 协议概述

    生活中有舒适区,借口成为懒惰的护身符,学习也有舒适区,逃避便是阻止进步的最大障碍. 经过半年多嵌入式方面的工作和学习,我提高了很多,但同时我也对自己所面临的问题逐渐清晰: 1. 偏于实践,理论基础不牢 ...

  4. TCP/IP协议学习之实例ping命令学习笔记

    TCP/IP协议学习之实例ping命令学习笔记(一) 一. 目的为了让网络协议学习更有效果,在真实网络上进行ping命令前相关知识的学习,暂时不管DNS,在内网中,进行2台主机间的ping命令的整个详 ...

  5. TCP/IP协议学习笔记

    计算机网络基础知识复习汇总:计算机网络基础知识复习 HTTP协议的解析:剖析 HTTP 协议 一个系列的解析文章: TCP/IP详解学习笔记(1)-- 概述 TCP/IP详解学习笔记(2)-- 数据链 ...

  6. tcp/ip协议学习笔记一

    一. 简述 以前在学校学习计算机网络的时候学习多是网络7层模型OSI,了解了一些基本的计算机网络概念和协议通信格式,但是一直没弄明白其中的原理,包括各层之间的关系,应用,还有一些常见的令牌环网到底是什 ...

  7. TCP/IP协议学习-1.概述

    目录 TCP/IP协议概述 分层 延伸知识 FTP例子 为什么需要网络层和传输层 TCP/IP的分层 封装 分用 总结 本文主要摘抄自书籍<TCP/IP详解卷一:协议>与TCP协议相关内容 ...

  8. TCP/IP协议学习和理解

    TCP:Transmission Control Protocol-传输控制协议 IP:Internet Protocol-网络协议 TCP/IP 不是一个协议,而是一个协议族的统称,里面包括了 IP ...

  9. TCP/IP协议学习

    计算机网路学得不好,首先先放个OSI七层网络模型吧 在协议的控制下,上层对下层进行调用,下层对上层进行服务, 上下层间用交换原语交换信息.这样可以提高传输速率,并且保证数据安全,所以说其实每一层都有存 ...

随机推荐

  1. Buge's Fibonacci Number Problem

    Buge's Fibonacci Number Problem Description snowingsea is having Buge’s discrete mathematics lesson, ...

  2. linux Centos下搭建gitolite服务器

    1.安装git sudo yum install git -y 2.添加git管理账号 sudo adduser git 3.将gitolite克隆到本地,并安装 sudo mkdir /var/gi ...

  3. 【001:C# 中 get set 简写存在的陷阱】

    如下代码: public class Age { private int ageNum ; public int AgeNum { get{ return this.ageNum; } set{ th ...

  4. iOS多线程同步锁

    在iOS中有几种方法来解决多线程访问同一个内存地址的互斥同步问题: 方法一,@synchronized(id anObject),(最简单的方法)会自动对参数对象加锁,保证临界区内的代码线程安全 @s ...

  5. Linux部署Apache ActiveMQ 5.14.1

    简单记一下,下载地址 http://activemq.apache.org/download.html 一.安装JDK7以上,官方说明:http://activemq.apache.org/versi ...

  6. android使用默认程序进行图片拍照已经裁剪,以及设备读取

    //代码如下: package com.cbsw.yulechangsuo.activity; import java.io.File;import java.io.FileInputStream;i ...

  7. JS调用JCEF方法

    坐下写这篇文章的时候,内心还是有一点点小激动的,折腾了一个多星期,踩了一个又一个的坑,终于找到一条可以走通的路,内心的喜悦相信经历过的人都会明白~~~~~今儿个老百姓啊,真呀个真高兴啊,哈哈,好了,废 ...

  8. php编译安装报错:make: *** [sapi/cli/php] Error 1 解决办法

    ext/iconv/.libs/iconv.o: In function `php_iconv_stream_filter_ctor':/ext/iconv/iconv.c:2491: undefin ...

  9. python 学习笔记十八 django深入学习三 分页,自定义标签,权限机制

    django  Pagination(分页) django 自带的分页功能非常强大,我们来看一个简单的练习示例: #导入Paginator>>> from django.core.p ...

  10. log4j日志配置

    #debug#日志权限配置log4j.rootLogger=info,error,stdout#控制台输出log4j.appender.stdout=org.apache.log4j.ConsoleA ...