疯狂Java讲义:使用ServletSocket创建TCP服务器端

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了疯狂Java讲义:使用ServletSocket创建TCP服务器端相关的知识,希望对你有一定的参考价值。

参考技术A

   使用ServletSocket创建TCP服务器端

  从图 中看上去TCP通信的两个通信实体之间并没有服务器端 客户端之分 但那是两个通信实体已经建立虚拟链路之后的示意图 在两个通信实体没有建立虚拟链路之前 必须有一个通信实体先做出 主动姿态 主动接收来自其他通信实体的连接请求

  Java中能接受其他通信实体连接请求的类是ServerSocket ServerSocket对象用于监听来自客户端的Socket连接 如果没有连接 它将一直处于等待状态 ServerSocket包含一个监听来自客户端连接请求的方法

  Socket accept() 如果接收到一个客户端Socket的连接请求 该方法将返回一个与客户端Socket对应的Socket(如图 所示每个TCP连接有两个Socket) 否则该方法将一直处于等待状态 线程也被阻塞

  为了创建ServerSocket对象 ServerSocket类提供了如下几个构造器

  ServerSocket(int port) 用指定的端口port来创建一个ServerSocket 该端口应该是有一个有效的端口整数值 ~

  ServerSocket(int port int backlog) 增加一个用来改变连接队列长度的参数backlog

  ServerSocket(int port int backlog InetAddress localAddr) 在机器存在多个 IP地址的情况下 允许通过localAddr这个参数来指定将ServerSocket绑定到指定的IP地址

  当ServerSocket使用完毕 应使用ServerSocket的close()方法来关闭该ServerSocket 通常情况下 服务器不应该只接受一个客户端请求 而应该不断地接受来自客户端的所有请求 所以Java程序通常会通过循环 不断地调用ServerSocket的accept()方法 如下代码片段所示

  //创建一个ServerSocket 用于监听客户端Socket的连接请求

  ServerSocket ss = new ServerSocket( )

  //采用循环不断接受来自客户端的请求

  while (true)

  

  //每当接受到客户端Socket的请求 服务器端也对应产生一个Socket

  Socket s = ss accept()

  //下面就可以使用Socket进行通信了

  …

  

  上面程序中创建ServerSocket没有指定IP地址 则该ServerSocket将会绑定到本机默认的IP地址 程序中使用 作为该ServerSocket的端口号 通常推荐使用 以上的端口 主要是为了避免与其他应用程序的通用端口冲突

       返回目录 疯狂Java讲义

       编辑推荐

       Java程序性能优化 让你的Java程序更快 更稳定

       新手学Java 编程

lishixinzhi/Article/program/Java/hx/201311/27266

Ajax疯狂讲义

Ajax: async javascript and xml 异步的JS和XML

AJAX 是一种用于创建快速动态网页的技术。 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。

Ajax创建四步法

我们都知道一个完整的Ajax动态网页的实现方法为:

var xhr = new XMLHttpRequest;
xhr.open("get","url",true);
xhr.onreasystatechange = function () {
    "code gose there";
}
xhr.send(string);

下面我们就详细的解释一下上述的四个步骤。

AJAX -  创建一个Ajax XMLHttpRequest 对象


XMLHttpRequest 是 AJAX 的基础。

XmlHttpRequest 术语缩写为XHR,中文可以解释为可扩展超文本传输请求。 

所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象。(IE5 和 IE6 使用 ActiveXObject)。

XMLHttpRequest 用于在后台与服务器交换数据。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

为了应对所有的现代浏览器,包括 IE5 和 IE6,请检查浏览器是否支持 XMLHttpRequest 对象。如果支持,则创建 XMLHttpRequest 对象。如果不支持,则创建 ActiveXObject ::

function createXHR() {
        var xhr = null;
        if (window.XMLHttpRequest) {
            xhr = new XMLHttpRequest;
        } else {
            try {
                xhr = new ActiveXobject("Microsoft.XMLHTTP");
            } catch (e) {
                try {
                    xhr = new ActiveXObject("Msxml2.XMLHTTP");
                }
                catch (e) {         
                }
            }
        }
        return xhr;
    }
var xhr = createXHR();

知上面的createXHR()方法每创建一个xhr对象,都会把createXHR方法执行一遍。由于我们第一次执行的时候就已经知道该浏览器下支持哪个new方法。但是第二次执行createXHR方法的时候就仍需要再全部重新执行一遍。这显然会增加系统的开销。所以我们可以用惰性思想的编程方式把支持浏览器的那个new方法返回来,这样就不需要每次执行时都把全部的代码执行一遍。

优化代码代码如下:

function createXHR() {
            var xhr = null,
                flag = false,
                arr = [
                    function () {
                        return new XMLHttpRequest;
                    },
                    function () {
                        return new ActiveXObject("Microsoft.XMLHTTP");
                    },
                    function () {
                        return new ActiveXObject("Msxm12.XMLHTTP");
                    }
                ];
            for (var i = 0; i < arr.length; i++) {
                var curFn = arr[i];
                try {
                    xhr = curFn();
                    //本次循环获取的方法没有出现错误:说明此方法是我想要的,我们下一次直接执行这个方法即可,,这就需要我把createXHR重写为本次循环得到的方法(完成后不需要再判断下面的,直接退出循环即可)
                    createXHR = curFn;
                    flag = true;
                    break;
                } catch (e) {
                    //本次循环获取的方法执行时出现错误:继续执行下一次循环
                }
                if (!flag) {
                    throw new Error("your browser is not support ajax,please change your browser,try again!");
                }
                
            }
            return xhr;
        }
var xhr = createXHR();

AJAX - 向服务器发送请求

XMLHttpRequest 对象用于和服务器交换数据。

当你的页面全部加载完毕后,客户端会通过 XMLHttpRequest 对象向服务器请求数据,服务器端接受数据并处理后,向客户端反馈数据。

如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open() 和 send() 方法:

xhr.open(method,url,async);
xhr.send(string);
  • 规定请求的类型、URL 以及是否异步处理请求。

    open(method,url,async)

      method:请求的类型;GET 或 POST

      url:文件在服务器上的位置,该文件可以是任何类型的文件

      async:true(异步)或 false(同步)

  • XMLHttpRequest 对象如果要用于 AJAX 的话,其 open() 方法的 async 参数必须设置为 true。因为当设置成false(即同步)时,JavaScript 会等到服务器响应就绪才继续执行。如果服务器繁忙或缓慢,应用程序会挂起或停止。

   设置为true后,JavaScript 无需等待服务器的响应,而是:

    在等待服务器响应时执行其他脚本。

    当响应就绪后对响应进行处理。

  • send(string)

    将请求发送到服务器。

    string:仅用于 POST 请求,send方法也可以不传参数,不传参数的话,表示不向服务器发送请求数据

AJAX - 服务器响应

由于 HTTP 响应是由服务端发出的,并且服务器做出响应需要时间(比如网速慢等原因),所以我们需要监听服务器响应的状态,然后才能进行处理。
获取来自服务器的响应,使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性。
  - xhr.responseText属性是获取字符串形式的响应数据
  - xhr.responseXML属性是获取XML形式的响应数据

AJAX - onreadystatechange 事件

当发送一个请求后,客户端需要确定这个请求什么时候会完成,因此,XMLHttpRequest对象提供了 onreadystatechange 事件机制来捕获请求的状态,继而实现响应。

当请求被发送到服务器时,我们需要执行一些基于响应的任务。每当 readyState改变时,就会触发 onreadystatechange 事件。readyState 属性存有 XMLHttpRequest 的状态信息。

下面是 XMLHttpRequest 对象的三个重要的属性:

  • xhr.onreadystatechange

    存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。onreadystatechange  

  • xhr.readyState      

    存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。

      0:UNSET             请求未初始化,还没有调用open()。

      1:OPENED            请求已经建立,但是还没有发送,open()已被调用,还没有调用send()。  

      2:HEADER_RECEIVED        请求已发送,已经调用send()函数。正在处理中(通常现在可以从响应中获取内容头)。  

      3:LOADING           请求在处理中;通常响应中已有部分数据可用了,没有全部完成。  

      4:LOADED            响应已完成;响应主体的内容已经成功返回到客户端(解析完成)

  • xhr.status:HTTP状态码,描述了服务器响应内容的状态

      200   OK /^2\d{2}/ (200或2开头的数字) 都代表响应主体的内容已经成功返回了


      301   永久重定向/永久转移
      302   临时重定向/临时转移
      304   本次获取的内容是读取缓存中的数据


      400   客户端传递给服务器的参数出现错误
      401   无权限访问
      404   客户端访问的地址不存在

      500   未知的服务器错误
      503   服务器已经超出负荷

  当 readyState 等于 4 且状态为 200 时,表示响应已就绪:在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务。

编写一个简易的Ajax方法库

由于每次编写Ajax方法都需要写下上面完整的Ajax四步,这无疑增加了我们的工作量。下面我们来编写一个一个Ajax方法,我们只需要调用这个方法就可以实现Ajax的XMLHttpRequest请求。

//ajax:实现AJAX请求的公共方法:当一个方法传递的参数值过多,而且不固定,我们使用对象统一传值法(需把要传递的参数值都先放在一个对象options中,一起传递进去即可)
    function ajax(options) {
        var _default = {
            url : "", //请求的地址
            type : "get",    //请求的方式
            dataType : "json",    //设置请求回来的内容格式"json"(即json格式的对象)。"txt"就是字符串或json格式的字符串
            async : true,    //请求是同步还是异步
            data : null,    //放在请求主体中的内容(POST)
            getHeaders : null,    //当READYSTATE===2时执行的回调函数
            success : null    //当readystate===4时执行的回调函数
        }
        for (var key in options) {
            if (options.hasOwnProperty(key)) {
                _default[key] = options[key];
            }
        }
        //如果当前的请求方式是GET,我们需要在URL的末尾添加随机数清除缓存
        if (_default[type] === "get") {
            _deauult[url].indexOf("?") >= 0 ? _default[url] += "&" :_default[url] += "?";
            _default[url] += "_=" + Math.random(); 
        }
        var xhr = createXHR();
        xhr.open(_default[type],_default[url],_default[async]);
        xhr.onreadystatechange = function () {
            if (/^2\d{2}$/.test(xhr.status)) {
                //想要在readystate=2的时候做一些操作,需要保证ajax是异步请求
                if (xhr.readyState === 2) {
                    if (typeof(_default[getHeaders]) === "function") {
                        _default[getHeaders].call(xhr);
                    }
                    
                }
                if (xhr.readyState == 4) {
                    var val = xhr.responseText;
                    if (_default.dataType === "json") {
                        val = "JSON" in window ? JSON.parse(val) : eval("(" + val + ")");
                    }
                    if (typeof(_default[success]) === "function") {
                        _default[success].call(xhr,val);
                    };//_default[success] && _default[success].call(xhr,val);
                    
                }
            }
        }
        xhr.send(_default[data]);//向请求主体传内容,但open方法中必须使用post请求方式
    }

 












以上是关于疯狂Java讲义:使用ServletSocket创建TCP服务器端的主要内容,如果未能解决你的问题,请参考以下文章

《疯狂Java讲义》(十六)---- 枚举类

《疯狂Java讲义》---- 数据类型

《疯狂Java讲义》(十九)---- 与用户交互

《疯狂Java讲义》(二十二)---- 正则表达式

《疯狂Java讲义》 3-数据类型与运算符

《疯狂Java讲义》(十八)---- JAR文件