第一章 网络应用程序
来源:互联网 发布:mac是什么意思啊 编辑:程序博客网 时间:2024/06/05 19:36
1.1 网络插座Socket
Socket开发网络应用程序时,首先考虑使用网络类型,主要包括以下三个方面:
1)Socket类型,使用网络协议的类别,IPV4的类型为PF_INET;
2)数据通信的类型,常见的数据报(SOCK_DGRAM)、数据流(SOCK_STREAM);
3)使用的网络协议,比如:TCP协议。
在同一个网络地址上,为了区分使用相同协议的不同应用程序,可以为不同的应用程序分配一个数字编号,这个编号为网络端口号(port)。取值范围0-65525。端口号分为三类,第一类是0-1023,称为总所周知的端口,有IANA进行控制和分配,由特定的网络程序使用,例如,TCP协议使用的80号端口来完成HTTP协议的传输。第二类的范围是1024-49151,称为登记端口,这些端口不由IANA控制,但是IANA维护了一个登记的列表,如果没有在IANA登记的话,也不应该在程序中使用,也可以在没有冲突的情况下自定义使用。第三类是49152-65535,称为动态或私有端口,这些由用户程序使用。
public class FreshManSocket { public void SimpleWebSocket() { //获得本机的loopback网络地址,即127.0.0.1 IPAddress address = IPAddress.Loopback; //创建可以访问的端口,49152表示端口号,如果设置为0,表示使用一个空闲的端口号 IPEndPoint endPoint = new IPEndPoint(address, 49152); //创建socket,使用IPv4地址,传输控制协议TCP,双向,可靠,基于连接的字节流 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //将socket绑定到一个端点上 socket.Bind(endPoint); //设置连接队列的长度 socket.Listen(10); Console.WriteLine("开始监听,端口号:{0}。", endPoint.Port); while (true) { //开始监听,这个地方会阻塞线程的执行,知道接受到一个客户端的连接请求 Socket client = socket.Accept(); //输出客户端的地址 Console.WriteLine(client.RemoteEndPoint); //准备读取客户端请求的数据,读取的数据将保存在一个数组中 byte[] buffer = new byte[4096]; //接受数据 int length = client.Receive(buffer, 4096, SocketFlags.None); //将请求的数据翻译为UTF-8 Encoding utf8 = Encoding.UTF8; string requestString = utf8.GetString(buffer, 0, length); //显示请求的消息 Console.WriteLine(requestString); //回应的状态行 const string statusLine = "HTTP/1.1 200 OK \r\n"; byte[] statusLineBytes = utf8.GetBytes(statusLine); //准备发送到客户端的网页 const string responseBody = "<html><head><title>From Socket Server</title></head><body><h1>FreshMan,Hello,My name is world.</h1></body></html>"; byte[] responseBodyBytes = utf8.GetBytes(responseBody); //回应的头部 string responseHeader = string.Format("Content-Type:text/html;charset=UTF-8\r\nContent-Length:{0}\r\n", responseBody.Length); byte[] responseHeaderBytes = utf8.GetBytes(responseHeader); //向客户端发送状态信息 client.Send(statusLineBytes); //向客户端发送回应头 client.Send(responseHeaderBytes); //头部与内容的分隔行 client.Send(new byte[] { 13, 10 }); //向客户端发送内容部分 client.Send(responseBodyBytes); //断开与客户端的连接 client.Close(); if (Console.KeyAvailable) { break; } } socket.Close(); } }
1.2 基于TCPListener的web服务器
为了简化基于TCP协议的监听程序,.NET在System.Net.Socket命名空间中提供了TCPListener类,使用他,在构造函数中传递一组网络端点信息就可以准备好监听参数,而不再需要设置使用的网络协议细节,调用Start方法之后,监听工作就开始了。AcceptTCPClient方法将阻塞进程,直到一个客户端的连接到达监听器,这个方法将返回一个代表客户端连接的代理对象,它的类型为TCPClient,可以通过它与客户端进行通信。
在输入输出部分,NetworkStream这个派生自Steam对象的字节流对象,对Socket的输入和输出进行了封装。
/// <summary> /// 使用Socket通信 /// </summary> public void SimpleTcpListener() { //获得本机的loopback网络地址,即127.0.0.1 IPAddress address = IPAddress.Loopback; //创建可以访问的端口,49152表示端口号,如果设置为0,表示使用一个空闲的端口号 IPEndPoint endPoint = new IPEndPoint(address, 49152); //TCP监听器 TcpListener newServer = new TcpListener(endPoint); //启动监听器 newServer.Start(); Console.WriteLine("开始监听,端口号:{0}。", endPoint.Port); while (true) { //等待客户端连接 TcpClient newClient = newServer.AcceptTcpClient(); Console.WriteLine("已建立连接!"); //得到一个网络流 NetworkStream ns = newClient.GetStream(); //将请求的数据翻译为UTF-8 Encoding utf8 = Encoding.UTF8; byte[] request = new byte[4096]; int length = ns.Read(request, 0, 4096); string requestString = utf8.GetString(request, 0, length); //显示请求的消息 Console.WriteLine(requestString); //回应的状态行 const string statusLine = "HTTP/1.1 200 OK \r\n"; byte[] statusLineBytes = utf8.GetBytes(statusLine); //准备发送到客户端的网页 const string responseBody = "<html><head><title>From Socket Server</title></head><body><h1>FreshMan,Hello,My name is world.</h1></body></html>"; byte[] responseBodyBytes = utf8.GetBytes(responseBody); //回应的头部 string responseHeader = string.Format("Content-Type:text/html;charset=UTF-8\r\nContent-Length:{0}\r\n", responseBody.Length); byte[] responseHeaderBytes = utf8.GetBytes(responseHeader); //向客户端发送状态信息 ns.Write(statusLineBytes, 0, statusLineBytes.Length); //向客户端发送回应头 ns.Write(responseHeaderBytes, 0, responseHeaderBytes.Length); //头部与内容的分隔行 ns.Write(new byte[] { 13, 10 }, 0, 2); //向客户端发送内容部分 ns.Write(responseBodyBytes, 0, responseBodyBytes.Length); //断开与客户端的连接 newClient.Close(); if (Console.KeyAvailable) { break; } } newServer.Stop(); }
1.3 基于HttpListener的Web服务器
为了进一步简化HTTP协议的监听器,.NET在命名空间System.Net中提供了HttpListener类。只有在Windows XP SP2或者Server 2003以上的操作系统中才能使用。
HttpListener类进一步简化了监听操作,仅需通过字符串的方法提供监听的地址,端口号,以及虚拟路径,就可以开始监听工作。开始监听后,GetContext方法将阻塞线程,当客户端的请求到达之后,HttpListener返回一个HttpListenerContext对象作为处理客户端请求的总代理,通过代理对象的Request属性,可以得到一个HttpListenerRequest的代表请求参数的对象,这个对象将大多数请求参数进行了对象化。
1.4 Web应用程序域
程序集管理的最小逻辑单位为应用程序域(AppDomain),对于.Net程序来说,可以动态加载程序集到应用程序域中。但是,加载之后的程序集不能单独卸载,只能以应用程序域为单位来整体卸载,应用程序域提供了四个重要的机智。
1)隔离,不同应用程序域之间不能直接访问。跨应用程序域访问的对象必须派生自System.MarshalByRefObject;管理程序将可以得到一个远程对象的代理对象,通过这个代理对象访问位于Web应用程序域中的对象;
2)卸载,被加载的程序集只能以应用程序域为单位卸载;
3)安全,以应用程序域为边界的安全机制;
4)配置,以应用程序域为边界的程序配置。
ApplicationHost类的静态方法CreateApplicationHost可以帮助我们非常简单的创建Web应用程序所需要的应用程序域,并设置所有需要的参数:
public static object CreateApplicationHost(Type hostType,string virtualDir,string physicalDir)其中:
hostType表示用来跨域访问的通信对象,它必须派生自MarshalByRefObject基类;
virtualDir表示网站应用程序的根所对应的虚拟目录;
physicalDir表示网站应用程序所在的文件系统的文件目录;
特别注意:
需要创建一个新的应用程序域,这个应用程序域将重新加载hostType,方法将按照以下顺序来寻找定义hostType类型的程序集;
1)GAC;
2)网站物理文件目录下的bin文件夹
准备用于处理的请求,必须封装为HttpWorkerRequest类型的对象,这是一个抽象类,定义在System.Web命名空间中,类型定义如下:public abstract class HttpWorkerRequest;通过这个类的对象实例,必须提供关于处理请求所需要的信息,以便于服务器处理请求。
System.Web.HttpRunting类是整个ASP.NET服务器处理的入口。提供了一系列的静态属性,反映了web应用程序域的设置信息。属性表:
HttpRuntime的静态方法ProcessRequest将帮助我们开始HTTP的处理之旅。方法定义如下:
Public static void ProcessRequest(HttpWorkerRequest wr)将HttpWorkerRequest对象传递给ProcessRequest方法,ASP.Net就开始服务器的请求处理任务了。
1.5 请求,响应参数的对象类型HttpRequest,HttpResponse
对于每一个请求参数,HttpRuntime将创建一个类型为HttpRequest的对象实例,这个类型定义在命名空间System.Web中:public sealed class HttpRequest。在HTTP的请求消息中,包好三部分内容:请求行、请求头部、请求主体。
HttpMethod表示请求的方式,这是一个只读的属性,返回字符串形式的请求方式;
RawUrl属性表示在HTTP请求消息中的原始请求地址,这是一个字符串形式的请求地址表示方式。
QueryString表示GET请求的参数集合,这是一个NameValueCollection类型的集合,提供两种索引器,可以通过顺序号或参数名称来获取参数的值。对于请求头都保存在一个集合中,这个集合的类型也是NameValueCollection类型,通过Headers属性可以获取到。定义如下:
Public NameValueCollection Headers{get;}
对于消息中的Cookie来说,由于Cookie可能有多个,所以在HttpRequest中通过HttpCookieCollection集合类型表示,这个集合可以通过Cookies属性得到。定义如下:
Public HttpCookieCollection Cookies{get;}
请求Body部分,Form为NameValueCollection的集合。定义如下:
Public NameValueCollection Form{get;}
有多个文件,处理成HttpFileCollection类型的集合,通过Files属性提供。定义如下:
Public HttpFileCollection File{get;}这个集合中的元素类型为HttpPostedFile,public sealed calss HttpPostedFile,重要成员:
向客户端返回请求的回应内容,同样定义代表回应的类型:HttpResponse类,它也定义在System.Web命名空间下,提供向客户端回应的方法和属性。HttpResponse类中的属性和方法:
回应消息中包含了三个部分的内容:状态行、头部、主体部分。对于没有对应属性的回应头,可以通过AddHeader方法来处理。这个方法接收两个字符串类型的参数,一个回应头的名称,一个就是回应头所对应的值。Public void AppendHeader(string name,string value)。
回应的内容部分是通过流来完成的,HttpResponse对象的OutputStream属性引用了输出到HTTP回应的输出流,这个属性定义如下:public Stream OutputStream(get;)
在HTTP的消息中,头部必须在主体部分的前面,所以,在已经输出主体部分之后,是不能再次输出消息头的。默认情况下,HttpResponse对输出的内容进行了缓冲,所以,通过HttpResponse输出的内容并没有立即输出到HTTP中,还可以修改。这时,是可以在使用输出流之后再次设置回应头的。但是,关闭了HttpResponse的缓冲,那么这样做就会报错。HttpResponse的BufferOutput属性是一个bool类型的属性,用于设置是否缓冲输出的内容。
辅助工具类HttpServerUtility提供一些常用的辅助方法。
MapPath方法是使用最多的一个辅助方法,用来将网站中的虚拟路径隐射到操作系统中的文件路径上。
浏览器特征:
Browser:浏览器的名称;
MajorVersion:主要版本;
MinorVersion:次要版本;
ClrVersion:CLR版本;
ActiveXControls:是否支持ActiveX控件;
Cookie:是否支持Cookie;
EcmaScriptVersion:支持的ECMA脚本的版本号;
W3CDowVersion:支持的W3C DOM的版本号。
常见的浏览器的特征文件保存在%System%\Microsoft.Net\Framework\版本\Config\Browsers文件夹下面,以.browser类型的文件形式提供。
- 第一章 网络应用程序
- 第一章:应用程序与窗口
- 第一章--java web应用程序概述
- 第一章 第一个OGRE应用程序
- 《深入浅出struts2》--第一章,Model2应用程序
- 第一章 开发简单java应用程序
- iPhone SDK 应用程序开发 第一章
- 网络英语 第一章
- Windwos 网络编程 第一章
- 第一章---网络基础知识
- 网络基础知识 第一章上
- python 网络编程第一章
- 第一章 网络编程入门
- UNIX网络编程 第一章
- Java网络编程第一章
- 【网络攻防】第一章 准备
- 第一章 初见网络爬虫
- 第一章java网络编程入门
- Marklogic学习 由浅入深(8)—— Hello World!
- Linux程序设计--进程
- Activity的启动模式
- C语言:统计各种字符的个数
- linux chmod命令
- 第一章 网络应用程序
- 构造函数与this
- 一个简单的可以接收TCP客户端数据的TCP服务器
- 1619-7 张良 十月二十一号总结 [连续第二十一天]
- 云立方ADSL动态拨号vps主机linux拨号使用说明
- Android InputMethodManager输入法简介
- poj1716 Integer Intervals(差分约束)
- 文件锁之flock()函数
- 防止数据重复提交