Chapter 1: A Simple Web Server

这算是一篇读书笔记,留着以后复习看看。

Web Server又称为Http Server,因为它使用HTTP协议和客户端(一般是各种各样的浏览器)进行通信。

什么是HTTP协议呢?

HTTP协议是基于有状态的TCP协议(默认的的TCP端口是80),最早版本的HTTP协议是HTTP/0.9,然后被HTTP/1.0代替了,代替HTTP/1.0的是现在使用的HTTP/1.1,详细介绍可以看RFC(请求注释)文档:http://www.w3.org/Protocols/HTTP/1.1/rfc2616.pdf。在HTTP协议中,总是客户端发起一个请求,服务器端是不会向客户端发起请求的。不管是客户端还是服务器端,都可以随时结束请求。

一个HTTP请求是由3部分组成的,请求行+请求头+请求实体,如下面这样

POST /examples/default.jsp HTTP/1.1
Host: localhost
Connection: Keep-Alive
Content-Length: 33
Content-Type: application/x-www-form-urlencoded

lastName=Franks&firstName=Michael

NOTE:请求头和请求实体之间要有一个空行(如果不包含请求实体,那么请求头结束后也要有一个空行),并且请求实体结束了要有一个空行。这样就是一个合法的HTTP请求了。

NOTE:一个合法的HTTP请求,应该可以没有请求实体,但是请求行和请求头(猜想这个请求头Connection: 是必须的)是不可以少的。

下面用一个例子,通过手动构造HTTP请求,请求baidu服务器端

/**
 * Created by user on 14-1-11.
 */
public class TestSocket1 {
    public static void main(String[] args) throws Exception {
        //建立连接
        Socket socket = new Socket("www.baidu.com", 80);
        InputStream is = socket.getInputStream();
        OutputStream os = socket.getOutputStream();
        
        //发送请求
//        //发送请求 方法1
//        boolean autoFlush = true;
//        PrintWriter pw = new PrintWriter(os, autoFlush);
//        pw.println("GET / HTTP/1.1");
//        pw.println("Host: www.baidu.com");
//        pw.println("Connection: Close");
//        //NOTE: 即使没有请求体,请求头后面的回车换行也是不可以少的
//        pw.println();
        //发送请求 方法2
        String CRLF = "
";
        StringBuffer requestSb = new StringBuffer();
        requestSb.append("GET / HTTP/1.1").append(CRLF)
                 .append("Host: www.baidu.com").append(CRLF)
                 .append("Connection: Close").append(CRLF)
                 .append(CRLF);
        os.write(requestSb.toString().getBytes());
        os.flush();
/*        
      //发送请求 方法3 : 测试,请求头是必须的,请求行也是必须的(至少要有Connection: ) 
      String CRLF = "
";
      StringBuffer requestSb = new StringBuffer();
      requestSb.append("GET / HTTP/1.1").append(CRLF)
//               .append("Host: www.baidu.com").append(CRLF)
               .append("Connection: Close").append(CRLF)
               .append(CRLF);
      os.write(requestSb.toString().getBytes());
      os.flush();
*/        
        //读取响应
        BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        StringBuffer sb = new StringBuffer(1024 * 8);
        boolean loop = true;
        while(loop) {
            if(br.ready()) {
                int i = 0;
                while(i != -1) {
                    i = br.read();
                    sb.append((char)i);
                }
                loop = false;
            }
        }
        System.out.println(sb.toString());
        socket.close();
    }
}

结果如下:

HTTP/1.1 200 OK
Date: Sat, 11 Jan 2014 00:11:08 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: Close
Vary: Accept-Encoding
Set-Cookie: BAIDUID=E89438B4C3C8B9A5D360DA8EF0F30A79:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BDSVRTM=0; path=/
Set-Cookie: H_PS_PSSID=4848_4820_4787_1446_4261_4989_4897_4760_4883_4678; path=/; domain=.baidu.com
P3P: CP=" OTI DSP COR IVA OUR IND COM "
Expires: Sat, 11 Jan 2014 00:10:20 GMT
Cache-Control: private
Server: BWS/1.1
BDPAGETYPE: 1
BDQID: 0x9626313d91064e78
BDUSERID: 0

3d94
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><link rel="dns-prefetch" href="//s1.bdstatic.com"/><link rel="dns-prefetch" href="//t1.baidu.com"/><link rel="dns-prefetch" href="//t2.baidu.com"/><link rel="dns-prefetch" href="//t3.baidu.com"/><link rel="dns-prefetch" href="//t10.baidu.com"/><link rel="dns-prefetch" href="//t11.baidu.com"/><link rel="dns-prefetch" href="//t12.baidu.com"/><title>百度一下,你就知道</title><style >html,body{height:100%}html{overflow-y:auto}#wrapper{position:relative;_position:;min-height:100%}#content{padding-bottom:100px;text-align:center}#ftCon{height:100px;position:absolute;bottom:44px;text-align:center;width:100%;margin:0 auto;z-index:0;overflow:hidden}#ftConw{width:720px;margin:0 auto}body{font:12px arial;text-align:;background:#fff}body,p,form,ul,li{margin:0;padding:0;list-style:none}body,form,#fm{position:relative}td{text-align:left}img{border:0}a{color:#00c}a:active{color:#f60}.bg{background-image:url(http://s1.bdstatic.com/r/www/cache/static/global/img/icons_1529edac.png);background-repeat:no-repeat;_background-image:url(http://s1.bdstatic.com/r/www/cache/static/global/img/icons_c7284217.gif)}.c-icon{display:inline-block;width:14px;height:14px;vertical-align:text-bottom;font-style normal;overflow:hidden;background:url(http://s1.bdstatic.com/r/www/cache/static/global/img/icons_1529edac.png) no-repeat 0 0;_background-image:url(http://s1.bdstatic.com/r/www/cache/static/global/img/icons_c7284217.gif)}.c-icon-triangle-down-blue{background-position:-480px -24px}.c-icon-chevron-unfold2{background-position:-504px -24px}#u{color:#999;padding:4px 10px 5px 0;text-align:right}#u a{margin:0 5px}#u .reg{margin:0}#m{width:720px;margin:0 auto}#nv a,#nv b,.btn,#lk{font-size:14px}#fm{padding-left:110px;text-align:left;z-index:1}input{border:0;padding:0}#nv{height:19px;font-size:16px;margin:0 0 4px;text-align:left;text-indent:137px}.bdsug{position:absolute;width:418px;background:#fff;display:none;border:1px solid #817f82}.bdsug li{width:402px;color:#000;font:14px arial;line-height:25px;padding:0 8px;position:relative;cursor:default}.bdsug li.bdsug-s{background:#ebebeb}#fm .bdsug{top:31px}.bdsug-store span,.bdsug-store b{color:#7a77c8}.bdsug-store-del{font-size:12px;color:#666;text-decoration:underline;position:absolute;right:8px;top:0;cursor:pointer;display:none}.bdsug-s .bdsug-store-del{display:inline-block}.bdsug-ala{display:inline-block;border-bottom:1px solid #e6e6e6}.bdsug-ala h3{line-height:14px;background:url(http://www.baidu.com/img/sug_bd.png) no-repeat left center;margin:6px 0 4px 0;font-size:12px;font-weight:normal;color:#7b7b7b;padding-left:20px}.bdsug-ala p{font-size:14px;font-weight:bold;padding-left:20px}.s_ipt_wr{width:418px;height:30px;display:inline-block;margin-right:5px;background-position:0 -288px;border:1px solid #b6b6b6;border-color:#9a9a9a #cdcdcd #cdcdcd #9a9a9a;vertical-align:top}.s_ipt{width:405px;height:22px;font-size:16px;line-height:22px;font-family:arial;margin:5px 0 0 7px;background:#fff;outline:0;-webkit-appearance:none}.s_btn{width:95px;height:32px;padding-top:2px9;font-size:14px;background-color:#ddd;background-position:0 -240px;cursor:pointer}.s_btn_h{background-position:-240px -240px}.s_btn_wr{width:97px;height:34px;display:inline-block;background-position:-120px -240px;*position:relative;z-index:0;vertical-align:top}#lg img{vertical-align:top;margin-bottom:3px}#lk{margin:33px 0}#lk span{font:14px "宋体"}#lm{height:60px;line-height:15px}#lh{margin:16px 0 5px;word-spacing:3px}.tools{position:absolute;top:-4px;*top:10px;right:7px}#mHolder{width:62px;position:relative;z-index:296;display:none}#mCon{height:18px;line-height:18px;position:absolute;cursor:pointer}#mCon span{color:#00c;cursor:default;display:block;width:24px}#mCon .hw{text-decoration:underline;cursor:pointer;display:inline-block}#mCon .pinyin{display:inline-block}#mCon .c-icon-chevron-unfold2{margin-left:5px}#mMenu a{width:100%;height:100%;display:block;line-height:22px;text-indent:6px;text-decoration:none;filter:none9}#mMenu,#user ul{box-shadow:1px 1px 2px #ccc;-moz-box-shadow:1px 1px 2px #ccc;-webkit-box-shadow:1px 1px 2px #ccc;filter:progid:DXImageTransform.Microsoft.Shadow(Strength=2,Direction=135,Color="#cccccc")9}#mMenu{width:56px;border:1px solid #9b9b9b;list-style:none;position:absolute;right:27px;top:28px;display:none;background:#fff}#mMenu a:hover{background:#ebebeb}#mMenu .ln{height:1px;background:#ebebeb;overflow:hidden;font-size:1px;line-height:1px;margin-top:-1px}#cp,#cp a{color:#666}#seth{display:none;behavior:url(#default#homepage)}#setf{display:none}#sekj{margin-left:14px}#shouji{margin-right:14px}.c-btn,.c-btn:visited{color:#333 !important}.c-btn{display:inline-block;padding:0 14px;margin:0;height:24px;line-height:26px;font-size:13px;font-family:inherit;font-weight:normal;text-align:center;vertical-align:middle;filter:chroma(color=#000000);overflow:visible;*zoom:1;background-color:#f9f9f9;border:1px solid #d8d8d8;cursor:pointer;overflow:hidden}.c-btn:hover{border-color:#388bff}.c-btn:active{border-color:#a2a6ab;background-color:#f0f0f0;box-shadow:inset 1px 1px 1px #c7c7c7;-webkit-box-shadow:inset 1px 1px 1px #c7c7c7;-moz-box-shadow:inset 1px 1px 1px #c7c7c7;-o-box-shadow:inset 1px 1px 1px #c7c7c7}a.c-btn{text-decoration:none}button.c-btn{height:26px;_height:26px;_line-height:18px;*overflow:visible}button.c-btn::-moz-focus-inner{padding:0;border:0}.c-btn .c-icon{margin-top:5px}.c-btn-disable{color:#999 !important}.c-btn-disable:visited{color:#999 !important}.c-btn-disable:hover{border:1px solid #d8d8d8;cursor:pointer;cursor:default}.c-btn-disable:active{border-color:#d8d8d8;background-color:#f9f9f9;box-shadow:none;-webkit-box-shadow:none;-moz-box-shadow:none;-o-box-shadow:none}.c-btn-mini{padding-left:5px;padding-right:5px;height:18px;line-height:18px;font-size:12px}button.c-btn-mini{height:20px;_line-height:14px}.c-btn-mini .c-icon{margin-top:2px}.c-btn-large{height:28px;line-height:28px;font-size:14px;font-family:"微软雅黑","黑体"}button.c-btn-large{height:30px;_line-height:24px}.c-btn-large .c-icon{margin-top:7px;_margin-top:6px}.c-btn-primary,.c-btn-primary:visited{color:#fff !important}.c-btn-primary{background-color:#388bff;border-color:#3c8dff #408ffe #3680e6}.c-btn-primary:hover{border-color:#2678ec #2575e7 #1c6fe2 #2677e7;background-color:#388bff;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAMAAACuX0YVAAAABlBMVEVnpv85i/9PO5r4AAAAD0lEQVR42gEEAPv/AAAAAQAFAAIros7PAAAAAElFTkSuQmCC);background-repeat:repeat-x;box-shadow:1px 1px 1px rgba(0,0,0,0.4);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,0.4);-moz-box-shadow:1px 1px 1px rgba(0,0,0,0.4);-o-box-shadow:1px 1px 1px rgba(0,0,0,0.4)}.c-btn-primary:active{border-color:#178ee3 #1784d0 #177bbf #1780ca;background-color:#388bff;background-image:none;-moz-box-shadow:inset 1px 1px 1px rgba(0,0,0,0.15);-o-box-shadow:inset 1px 1px 1px rgba(0,0,0,0.15);-ms-box-shadow:inset 1px 1px 1px rgba(0,0,0,0.15);-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,0.15)}.c-btn .c-icon{float:left}#user,#user_center{z-index:2}.ws-tips{position:absolute;right:10px;top:54px;width:250px;height:78px;background:#fff;border:1px solid #e3e3e3;white-space:nowrap;z-index:1;border-bottom-color:#e0e0e0;border-right-color:#ececec;box-shadow:1px 2px 1px rgba(0,0,0,0.072);-webkit-box-shadow:0 2px 2px rgba(0,0,0,0.072);-moz-box-shadow:1px 2px 1px rgba(0,0,0,0.072);-o-box-shadow:0 2px 2px rgba(0,0,0,0.072)}.ws-tips img{vertical-align:middle;width:56px;height:56px;position:absolute;left:10px;top:10px}.ws-d-info{text-align:center;width:144px;height:46px;position:absolute;left:76px;top:15px}.ws-d-label{font-size:14px;font-family:'宋体';color:#666}.ws-d-label span{font-family:arial}#ws-btn{position:absolute;right:8px;top:8px;background:url('http://s1.bdstatic.com/r/www/cache/static/global/img/wsCloseBtn2_4a84c812.png') no-repeat;width:9px;height:9px}#ws-btn:focus{outline:0}.ws-d-info a{margin-top:6px;font:bold 12px/24px "宋体"}</style><script >function h(obj){obj.style.behavior='url(#default#homepage)';var a = obj.setHomePage('http://www.baidu.com/');}</script></head><body><div id="wrapper"><div id="content"><div id="u"><a href="http://www.baidu.com/gaoji/preferences.html" name="tj_setting">搜索设置</a>|<a href="https://passport.baidu.com/v2/?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2F" name="tj_login" id="lb" onclick="return false;">登录</a><a href="https://passport.baidu.com/v2/?reg&regType=1&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2F" target="_blank" name="tj_reg" class="reg">注册</a></div><div id="m"><p id="lg"><img src="http://www.baidu.com/img/bdlogo.gif" width="270" height="129"></p><p id="nv"><a href="http://news.baidu.com">&nbsp;</a> <b>&nbsp;</b> <a href="http://tieba.baidu.com">&nbsp;</a> <a href="http://zhidao.baidu.com">&nbsp;</a> <a href="http://music.baidu.com">&nbsp;</a> <a href="http://image.baidu.com">&nbsp;</a> <a href="http://v.baidu.com">&nbsp;</a> <a href="http://map.baidu.com">&nbsp;</a></p><div id="fm"><form name="f" action="/s"><span class="bg s_ipt_wr"><input type="text" name="wd" id="kw" maxlength="100" class="s_ipt"></span><input type="hidden" name="rsv_bp" value="0"><input type=hidden name=ch value=""><input type=hidden name=tn value="baidu"><input type=hidden name=bar value=""><input type="hidden" name="rsv_spt" value="3"><input type="hidden" name="ie" value="utf-8"><span class="bg s_btn_wr"><input type="submit" value="百度一下" id="su" class="bg s_btn" onmousedown="this.className='bg s_btn s_btn_h'" onmouseout="this.className='bg s_btn'"></span></form><span class="tools"><span id="mHolder"><div id="mCon"><span>输入法</span></div></span></span><ul id="mMenu"><li><a href="#" name="ime_hw">手写</a></li><li><a href="#" name="ime_py">拼音</a></li><li class="ln"></li><li><a href="#" name="ime_cl">关闭</a></li></ul></div><p id="lk"><a href="http://baike.baidu.com">百科</a> <a href="http://wenku.baidu.com">文库</a> <a href="http://www.hao123.com">hao123</a><span>&nbsp;|&nbsp;<a href="http://www.baidu.com/more/">更多&gt;&gt;</a></span></p><p id="lm"></p></div></div><div id="ftCon"><div id="ftConw"><p ><a id="seth" onClick="h(this)" href="/" onmousedown="return ns_c({'fm':'behs','tab':'homepage','pos':0})">把百度设为主页</a><a id="setf" href="http://www.baidu.com/cache/sethelp/index.html" onmousedown="return ns_c({'fm':'behs','tab':'favorites','pos':0})" target="_blank">把百度设为主页</a><span id="sekj"><a href="http://anquan.baidu.com/?wenzilian" target="_blank" onmousedown="return ns_c({'fm':'behs','tab':'bdbrwlk','pos':1})">安装百度卫士</a></span></p><p id="lh"><a href="http://e.baidu.com/?refer=888" onmousedown="return ns_c({'fm':'behs','tab':'btlink','pos':2})">加入百度推广</a>&nbsp;|&nbsp;<a onmousedown="return ns_c({'fm':'behs','tab':'tj_bang'})" href="http://top.baidu.com">搜索风云榜</a>&nbsp;|&nbsp;<a onmousedown="return ns_c({'fm':'behs','tab':'tj_about'})" href="http://home.baidu.com">关于百度</a>&nbsp;|&nbsp;<a onmousedown="return ns_c({'fm':'behs','tab':'tj_about_en'})" href="http://ir.baidu.com">About Baidu</a></p><p id="cp">&copy;2014&nbsp;Baidu&nbsp;<a href="/duty/" name="tj_duty">使用百度前必读</a>&nbsp;京ICP证030173号&nbsp;<img src="http://www.baidu.com/cache/global/img/gs.gif"></p></div></div></div><script>var bds={se:{},comm : {ishome : 1,sid : "4392_1434_4261_4988_4897_4760_4883_4677_4906",user : "",username : "",sugHost : "http://suggestion.baidu.com/su",loginAction : []}}</script><script type="text/javascript" src="http://s1.bdstatic.com/r/www/cache/static/jquery/jquery-1.10.2.min_f2fb5194.js" charset="utf-8"></script><script type="text/javascript" src="http://s1.bdstatic.com/r/www/cache/static/global/js/home_0a8a22db.js" charset="utf-8"></script><script>var bdUser = null;var w=window,d=document,n=navigator,k=d.f.wd,a=d.getElementById("nv").getElementsByTagName("a"),isIE=n.userAgent.indexOf("MSIE")!=-1&&!window.opera;(function(){if(/q=([^&]+)/.test(location.search)){k.value=decodeURIComponent(RegExp["x241"])}})();if(n.cookieEnabled){bds.se.sug({'form':$('#fm form')[0],'ipt':$('#kw')[0]});};function addEV(o, e, f){if(w.attachEvent){o.attachEvent("on" + e, f);}else if(w.addEventListener){ o.addEventListener(e, f, false);}}function G(id){return d.getElementById(id);}function ns_c(q){var p = encodeURIComponent(window.document.location.href), sQ = '', sV = '', mu='', img = window["BD_PS_C" + (new Date()).getTime()] = new Image();for (v in q) {sV = q[v];sQ += v + "=" + sV + "&";} mu= "&mu=" + p ;img.src = "http://nsclick.baidu.com/v.gif?pid=201&pj=www&rsv_sid=4392_1434_4261_4988_4897_4760_4883_4677_4906&" + sQ + "path="+p+"&t="+new Date().getTime();return true;}if(/bdime=[12]/.test(d.cookie)){document.write('<script src="' + "http://s1.bdstatic.com/r/www/cache/static/ime/js/openime_ceac1c4e.js" + '" charset="utf-8"></script>');}(function(){var u = G("u").getElementsByTagName("a"), nv = G("nv").getElementsByTagName("a"), lk = G("lk").getElementsByTagName("a"), un = "";var tj_nv = ["news","tieba","zhidao","mp3","img","video","map"];var tj_lk = ["baike","wenku","hao123","more"];un = bds.comm.user == "" ? "" : bds.comm.user;function _addTJ(obj){addEV(obj, "mousedown", function(e){var e = e || window.event;var target = e.target || e.srcElement;ns_c({'fm':'behs','tab':target.name||'tj_user','un':encodeURIComponent(un)});});}for(var i = 0; i < u.length; i++){_addTJ(u[i]);}for(var i = 0; i < nv.length; i++){nv[i].name = 'tj_' + tj_nv[i];}for(var i = 0; i < lk.length; i++){lk[i].name = 'tj_' + tj_lk[i];}})();(function() {var links = {'tj_news': ['word', 'http://news.baidu.com/ns?tn=news&cl=2&rn=20&ct=1&ie=utf-8'],'tj_tieba': ['kw', 'http://tieba.baidu.com/f?ie=utf-8'],'tj_zhidao': ['word', 'http://zhidao.baidu.com/search?pn=0&rn=10&lm=0'],'tj_mp3': ['key', 'http://music.baidu.com/search?fr=ps&ie=utf-8'],'tj_img': ['word', 'http://image.baidu.com/i?ct=201326592&cl=2&nc=1&lm=-1&st=-1&tn=baiduimage&istype=2&fm=&pv=&z=0&ie=utf-8'],'tj_video': ['word', 'http://video.baidu.com/v?ct=301989888&s=25&ie=utf-8'],'tj_map': ['wd', 'http://map.baidu.com/?newmap=1&ie=utf-8&s=s'],'tj_baike': ['word', 'http://baike.baidu.com/search/word?pic=1&sug=1&enc=utf8'],'tj_wenku': ['word', 'http://wenku.baidu.com/search?ie=utf-8']};var domArr = [G('nv'), G('lk'),G('cp')],kw = G('kw');for (var i = 0, l = domArr.length; i < l; i++) {domArr[i].onmousedown = function(e) {e = e || window.event;var target = e.target || e.srcElement,name = target.getAttribute('name'),items = links[name],reg = new RegExp('^\s+|\s+x24'),key = kw.value.replace(reg, '');if (items) {if (key.length > 0) {var wd = items[0], url = items[1],url = url + ( name === 'tj_map' ? encodeURIComponent('&' + wd + '=' + key) : ( ( url.indexOf('?') > 0 ? '&' : '?' ) + wd + '=' + encodeURIComponent(key) ) );target.href = url;} else {target.href = target.href.match(new RegExp('^http://.+.baidu.com'))[0];}}name && ns_c({'fm': 'behs','tab': name,'query': encodeURIComponent(key),'un': encodeURIComponent(bds.comm.user || '') });};}})();addEV(w,"load",function(){k.focus()});w.onunload=function(){};</script><script type="text/javascript" src="http://s1.bdstatic.com/r/www/cache/static/global/js/tangram-1.3.4c1.0_07038476.js"></script><script type="text/javascript" src="http://s1.bdstatic.com/r/www/cache/static/user/js/u_7b0ea87f.js" charset="utf-8"></script><script>try{document.cookie="WWW_ST=;expires=Sat, 01 Jan 2000 00:00:00 GMT";$(document.forms[0]).on("submit",function(){var _t=new Date().getTime();document.cookie = "WWW_ST=" + _t +";expires=" + new Date(_t + 10000).toGMTString()})}catch(e){}</script></body></html>

0

?

模仿how tomcat works第一章写的程序,地址:http://download.csdn.net/detail/hx888/6836501

运行效果

原文地址:https://www.cnblogs.com/wenwujuncheng/p/3514700.html