星期五 二月 26, 2010 15:50

超文本转移协议与万维网高速缓存

HTTP协议

HTTP是一个客户端和服务器端请求和应答的标准。从层次的角度看,HTTP是面向事务(所谓事务就是指一系列的信息交换,而这一系列交换是一个不可分割的整体,即要么所有的信息交换都完成,要么一次交换都不进行)的应用层协议,是万维网上能够可靠地交换文件的重要基础。

服务器进程不断的监听指定端口(默认端口为80),用来判断是否有浏览器(网络爬虫或其他客户进程)向它发出连接建立请求。当判断为真并建立连接之后,客户进程向源服务器(Origin Server)发出HTTP请求,源服务器响应,最后连接被释放。这样的操作交互遵循一定的规则与格式标准,而这个标准就是超文本转移协议HTTP。

HTTP虽然使用了TCP,但其本身是无状态的(stateless)。换句话说,同一个客户端第二次访问同一个服务器上的页面时,服务器的响应与第一次的相同。虽然TCP是面向连接的向上提供服务,但HTTP协议本身是无连接的

尽管TCP/IP协议是互联网上最流行的应用,但HTTP协议并没有规定必须使用它和(基于)它支持的层。 事实上,HTTP可以在任何其他互联网协议上,或者在其他网络上实现。HTTP只假定(其下层协议提供)可靠的传输,任何能够提供这种保证的协议都可以被其使用

HTTP报文

HTTP有两类报文,一种是请求报文,另一种是响应报文。它们都由三个部分组成。从下图不难看出,两种报文结构的开始行略有不同。

方法 空格 URL 空格 版本 CRLF
首部字段名: 空格 CRLF    
首部字段名: 空格 CRLF    
CRLF
实体主体(通常不用)

(a)  请求报文

版本 空格 状态码 空格 短语 CRLF
首部字段名: 空格 CRLF    
首部字段名: 空格 CRLF    
CRLF
实体主体(有些响应报文不用)

(b)  响应报文

1)    开始行,用于区分是请求报文还是响应报文。所有HTTP请求的第一行都是请求行,主要包含请求方法,请求资源的URL,以及HTTP的版本;而响应报文的开始行叫做状态行,主要包含HTTP的版本,状态码以及其对应的短语。它们都用空格隔开,CR代表回车,LF代表换行。

2)    首部(Head)行,用来描述浏览器(网络爬虫等)或服务器的一些信息。它可以有好几行,每一行都必须有CR与LF。整个首部行结束之后,还用一个CRLF将其与实体隔开。

3)    实体主体(Entity Body),请求报文中一般不用这个字段(只有请求方法要求时才会被放在请求消息中),而响应报文里也可以没有。

其中值得注意的是,状态代码的第一个数字代表当前响应的类型:

  • 1xx 消息——请求已被服务器接收,继续处理
  • 2xx 成功——请求已成功被服务器接收、理解、并接受
  • 3xx 重定向——需要后续操作才能完成这一请求
  • 4xx 请求错误——请求含有词法错误或者无法被执行
  • 5xx 服务器错误——服务器在处理某个正确请求时发生错误

虽然 RFC 2616 中已经推荐了描述状态的短语,例如”200 OK”,”404 Not Found”,但是 WEB 开发者仍然能够自行决定采用何种短语,用以显示本地化的状态描述或者自定义信息。

可以看到的是,HTTP仍在不断的发展。现在的较新的版本是1999年公布的HTTP/1.1[RFC 2616],它已成为因特网草案标准。而下一代HTTP(HTTP-NG)则正在研究之中

万维网高速缓存

万维网高速缓存(Web cache)是代理服务器的一种功能,它将最近的一些请求与响应暂存在代理服务器的本地磁盘中。如果新的请求与代理服务器的缓存吻合,则直接从代理服务器返回响应;反之,则需要按照请求的URL再次通过Internet访问该资源。其大致过程如下:

1)    客户端(浏览器)需要发送请求时,与带有Web Cache功能的代理服务器建立TCP连接,并向代理服务器发送HTTP请求报文。

2)    如果代理服务器已经存放了所请求的对象,则直接将其放入HTTP响应报文中返回给客户端(浏览器)。

3)    否则,代理服务器就代表客户端(浏览器),与Internet上的源服务器建立TCP连接,并发送HTP请求报文,源服务器把请求对象放在HTTP响应报文中返回给代理服务器。

4)    代理服务器获得该对象之后,先复制保存到本地磁盘(为其日后服务),再将该对象放在HTTP响应报文中,通过之前与客户端建立的TCP返回给用户(浏览器)。

其中,保存到本地磁盘以及返回响应之前,我们Ipv6项目还有很多事要做

星期二 二月 23, 2010 00:42

和阿Shi拍片

寒假在惆怅的走亲访友中消耗殆尽,尽管很不情愿,但“该来的”新学期,却挡也挡不住。好在,开学前和阿屎约好了,要一起出去玩玩单反,让我这个久居室内的宅男,也有机会品吸阳光的味道。

  • 拍摄地点:主要是解放公园和汉口江滩
  • 使用器材:Canon EOS 400D + EF 24-70 2.8L + EF 70-200 4L IS
  • 故事起因:由于头天夜里聊的很晚,睡得更晚,第二天又早早的被鞭炮吵醒,所以…
  • 故事人物:我和阿屎
  • 故事时间:2010春节
  • 故事梗概:完全是练手,纯粹俩傻小子满街乱转悠

瞌睡的鹦鹉

———————————————————

偷拍娃娃妞

———————————————————

偷拍娃娃妞

———————————————————

阿屎

呃,这一个就是阿屎了…

星期六 二月 20, 2010 16:56

落幕

落幕那一刻,多少会给人带来些许遗憾。

憋的太久——我从来不会,不敢,不主动的在大多数场合谈及自己的感情生活——那个酸酸的,甜甜的,斗志昂扬的,冰天雪地的,磕磕碰碰的,吵吵闹闹的,偷偷摸摸的,两个春夏秋冬。不算甜蜜但却刻骨铭心的瞬间,我总爱劝慰她说,把时间轴拉长来看。只是现在,真的是点滴便永恒,但却不再有更多的点点滴滴了。那一天,我故作理智的告诉她:“之所以借口多多,是因为爱的不够…”哪里晓得,如梦初醒的时候,才发现,生活中的每个细节都被她浸透!我努力的擦拭着痕迹,可每当不经意之间,悲情就爬满心头…才明白心能有多痛!才明白…!

she is my love

痛到没有知觉。没有了知觉,我又开始恢复理智,直到理智再被知觉吞噬,如此循环。那些清晰可见的回忆,触手可及的哀愁,在痛与不痛之间低吟…

人,从出生那一刻起,就不在单纯。所以他们说:合适的时间,遇到合适的人,才能孕育合适的感情,才能书写至少不算坏的结局。其实,结婚与恋爱毫无关系,人们老以为恋爱成熟后便自然而然的结婚,却不知结婚只是一种生活方式,人人可以结婚,简单得很。爱情……完全是另外一回事。

我感激那些纯真的情谊,至少,这一辈子,我拥有过。落幕…

星期二 十二月 22, 2009 09:17

cSharp中BackgroundWorker的用法

线程同步中,还有一个比较流行的类<BackgroundWorker>.

BackgroundWorker 类允许您在单独的专用线程上运行操作。耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用 BackgroundWorker 类方便地解决问题。

若要在后台执行耗时的操作,请创建一个 BackgroundWorker,侦听那些报告操作进度并在操作完成时发出信号的事件。可以通过编程方式创建BackgroundWorker,也可以将它从“工具箱”的“组件”选项卡中拖到窗体上。如果在 Windows 窗体设计器中创建 BackgroundWorker,则它会出现在组件栏中,而且它的属性会显示在“属性”窗口中。

若要设置后台操作,请为 DoWork 事件添加一个事件处理程序。在此事件处理程序中调用耗时的操作。若要启动该操作,请调用 RunWorkerAsync。若要收到进度更新通知,请对 ProgressChanged 事件进行处理。若要在操作完成时收到通知,请对 RunWorkerCompleted 事件进行处理。

下面这个例子,主要从这几个方面来谈 cancellation support and report progress

    public partial class Form1 : Form
    {
 
        public Form1()
        {
            InitializeComponent();
            this.backgroundWorker1.WorkerSupportsCancellation = true;
            this.backgroundWorker1.WorkerReportsProgress = true;
 
            this.backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
            this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
            this.backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
 
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            if (this.textBox1.Text != "" &amp;&amp; this.textBox2.Text != "")
            {
                ab a = new ab(int.Parse(this.textBox1.Text), int.Parse(this.textBox2.Text));
                this.backgroundWorker1.RunWorkerAsync(a);
            }
 
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            this.backgroundWorker1.CancelAsync();
        }
 
        void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.progressBar1.Value = e.ProgressPercentage;
        }
 
        void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                this.textBox3.Text = "Result :Canclled!";
                this.progressBar1.Value = 100;
            }
            else if (e.Error != null)
            {
                MessageBox.Show("Error Details : " + (e.Error as Exception).ToString());
            }
            else
            {
                    this.textBox3.Text = "Result :" + e.Result;
                    this.progressBar1.Value = 100;
             }
        }
 
        void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            //do something here backgroundly.
 
                for (int i = 0; i &lt; this.progressBar1.Maximum; i++)
                {
                    Thread.Sleep(50);
                    this.backgroundWorker1.ReportProgress(i);
 
                    if (this.backgroundWorker1.CancellationPending)
                    {
                        e.Cancel = true;
                        return;
                    }
 
                }
                ab a = (ab)e.Argument;
                e.Result = a.C;
 
            }
 
    }
 
    class ab
    {
        private int _a;
 
        public int A
        {
            get { return _a; }
            set { _a = value; }
        }
        private int _b;
 
        public int B
        {
            get { return _b; }
            set { _b = value; }
        }
        public ab(int a,int b)
        {
            this._a = a;
            this._b = b;
        }
 
        public int C
        {
            get { return _b + _a; }
        }
    }