zoukankan      html  css  js  c++  java
  • 1.一个简单的web服务器

    章前准备
    ServerSocket使用简介:
        jdk描述:此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。
        关键方法:1.ServerSocket(int port)   创建绑定到特定端口的服务器套接字。
                     2.accept()  侦听并接受到此套接字的连接。
        使用总结:建立ServerSocket后,通过accept不断获取Socket,并对获取的Socket进行数据的接收分析,和发送

    Socket使用简介:
        jdk描述:此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。
        关键方法:1.getInputStream() 返回此套接字的输入流。
                     2.getOutputStream() 返回此套接字的输出流。
        使用总结:建立Socket后,通过输入流传入请求数据,通过输出流获取响应数据,这里获取的全是字节流(小心乱码哦,亲)- -

    简单测试一:我们要建立连接

    /**
     * @author 程猿
     * 简单的创建了一个ServerSocket,观察使用方式
     *
     */
    public class Server {
    public static void main(String args[])throws Exception {
            ServerSocket server = new ServerSocket(8080);
            while (true) {
                    Socket socket = server.accept();
                    System.out.println("获取新的socket");
            }
    }
    }
    /**
     * @author 程猿
     * 创建Socket后即可进行与相应的服务端进行连接
     */
    public class Client {
        public static void main(String args[]) throws Exception {
            Socket socket = new Socket("127.0.0.1", 8080);
        }
    }

        启动Server后不断启动Client就会不断地打印出获取新的socket,可见Socket在新建时就已经尝试开始链接了,可以发现ServerSocket和Socket的一一对应仅仅跟地址,端口号相关
        虽然能够连接具有跨时代的意义,不过我还更在乎他们之间如何进行数据的交互/通信

    简单测试二:我们要让链接可以通信

    /**
     * 
     * @author 程猿
     *
     * 尝试使用输入输出流进行数据的接受与发送
     * InputStream:当对方中断后,我们才会停止,跳出
     */
    public class Server {
    public static void main(String args[])throws Exception {
            ServerSocket server = new ServerSocket(8080);
            while (true) {
                    Socket socket = server.accept();
                    System.out.println("get a socket");
                    //接受请求
                    InputStream inputStream = socket.getInputStream();
                    int i=0;
                    while((i=inputStream.read())!=-1){
                        System.out.print((char)i);
                    }
                    //发送回应
                    OutputStream outputStream = socket.getOutputStream();
                    outputStream.write("imok".getBytes());
                    socket.close();
                    System.out.println();
                    System.out.println("socket is over");
            }
    }
    }
    /**
     * @author 程猿
     * 因为服务端以(i=inputStream.read())!=-1为请求结束依据,在客户端就必须尝试关闭相应的OutputStream
     * 当然,直接关闭OutputStream会产生连锁问题...比如socket和InputStream都被关闭
     * 故使用了socket提供的单独关闭的方法...
     */
    public class Client {
        public static void main(String args[]) throws Exception {
            Socket socket = new Socket("127.0.0.1", 8080);
            
            OutputStream outputStream = socket.getOutputStream();
            outputStream.write("hry".getBytes());
            socket.shutdownOutput();
    //        outputStream.close();
            InputStream inputStream = socket.getInputStream();
            int i=0;
            while((i=inputStream.read())!=-1){
                System.out.print((char)i);
            }
        }
    
    }

    打开服务端

    1.点击测试二的Client,服务端会显示

    get a socket
    hry
    socket is ove

    2.开浏览器,输入127.0.0.1:8080,服务端显示:

    get a socket
    GET / HTTP/1.1
    Host: 127.0.0.1:8080
    User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
    Accept-Encoding: gzip, deflate
    Cookie: JSESSIONID=C8CD6B63C4FC2C05A3CA48D667F4A484
    Connection: keep-alive

    可以看到,服务端并没有结束...需要手动关闭,才能进行在进行下一个测试
    3.打开文件夹,输入 ftp://127.0.0.1:8080,服务端输出

    get a socket

    然后文件夹进入假死状态...强制关闭后输出

    Exception in thread "main" java.net.SocketException: Connection reset
        at java.net.SocketInputStream.read(SocketInputStream.java:168)
        at java.net.SocketInputStream.read(SocketInputStream.java:182)
        at t2.Server.main(Server.java:22)

    4.打开控制台(cmd),输入telnet 127.0.0.1 8080 ,在输入任意数,发现服务端将会依次显示任意数。。直到关闭控制台
      进入telnet后按ctrl+]在按回车,会有输入结果回写哦。。。(看不懂的话试试就知道了,无法用语言形容)
    5.打开qq,换上http代理,地址127.0.0.1,端口8080,点下测试玩玩(差不多就关了,就会出现socket is over,反正qq没假死对吧)

    get a socket
    CONNECT tcpconn2.tencent.com:443 HTTP/1.1
    Host: tcpconn2.tencent.com:443
    Accept: */*
    Content-Type: text/html
    Proxy-Connection: Keep-Alive
    Content-length: 0
    
    
    socket is over

    6.7你所能想到的所有可以发送请求,建立连接的方式,比如mstsc,svn,其他的代理方式。。。

    总结一下:

     当看到Client链接使用的是Socket而Server获取的也是Socket时,是否会认为他2是同一个对象呢...Client这边的Socket存在我们操作的电脑中,而Server中的Socket则存在为我们提供服务的电脑中(服务器),当然,我们可以通过类似于Socket和ServerSocket的机制,来创建一种消息机制(对他们进行封装),是他们接受的对象都相同
        在这个例子里面,因为使用(i=inputStream.read())!=-1判断请求是否中断的具体实现,所以对Client也有了一点的要求,可见前后台的交互必须遵照一定的约定才能够准确的进行通信,即不同的服务器要遵守不同的协议,而WEB服务器遵守的就是http协议(所以也叫HTTP服务器),再次强调链接仅仅与地址和ip相关,不遵守协议服务器只是不提供服务而已
            我们是要玩tomcat的男人,那就让serversocket依照http协议来一次,看看效果呗

    测试三之前:我们要了解一下http协议

    通过前面的测试,可以看到通信见相互传递的就是一些字节流,比如测试二.2中打印

    GET / HTTP/1.1
    Host: 127.0.0.1:8080
    User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
    Accept-Encoding: gzip, deflate
    Cookie: JSESSIONID=C8CD6B63C4FC2C05A3CA48D667F4A484
    Connection: keep-alive

    当然,这是web客户端(浏览器)发送的,肯定遵循HTTP协议,至于其详细内容要查看HTTP协议....好绕口,先不管这些,请求就是它了(反正Socket不用我们写,浏览器都是现成的)
    重点是响应是什么....我不否认firebug什么的是可以看到被整理过的请求和响应,但叔要的是最原始的...(好犯贱啊)
    我们可以先创建一个JavaWeb项目a,创建一个Servlet->a,然后在cmd中输入127.0.0.1:8080(记得启动tomcat),在输入

    GET /a/servlet/a HTTP/1.1
    Host:

    加两个回车输出

    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    Content-Type: text/html
    Transfer-Encoding: chunked
    Date: Wed, 29 Oct 2014 06:08:32 GMT
    
    bb
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <HTML>
      <HEAD><TITLE>A Servlet</TITLE></HEAD>
      <BODY>
        This is class a, using the GET method
      </BODY>
    </HTML>
    
    0

    就是响应流...有点像通过存在的服务器创建服务器一样...但这就是我们的优势

    测试三:我们要让server返回能被浏览器识别(遵守Http协议,实在没词了...)

    /**
     * @author 程猿
     * 浏览器竟然使用Http1.1协议....这货是个长链接,简单的说,通过(i=inputStream.read())!=-1来判断请求结束是不科学的
     * 还好,我发现在telnet中2发回车(
    ,
    )就可以获取响应,也许这就是他的结束标识
     */
    public class Server {
    
    public static void main(String args[])throws Exception {
            ServerSocket server = new ServerSocket(8080);
            while (true) {
                    Socket socket = server.accept();
                    //接受请求
                    InputStream inputStream = socket.getInputStream();
                    int i=0;
                    boolean flag=false;;
                    while((i=inputStream.read())!=-1){
                        if(i=='
    '&&flag==true){
                            break;
                        }
                        if(i=='
    '){
                            flag=true;
                        }else{
                            flag=false;
                        }
                        
                        System.out.print((char)i);
                    }
                    
                    //发送回应
                    OutputStream outputStream = socket.getOutputStream();
                String str = "HTTP/1.1 200 OK
    "
                        + "Server: Apache-Coyote/1.1
    "
                        + "Content-Type: text/html
    "
                        + "Transfer-Encoding: chunked
    "
                        + "Date: Wed, 29 Oct 2014 06:08:32 GMT
    "
                        + "
    "
                        + "bb
    "
                        + "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    "
                        + "<HTML>
    " + "  <HEAD><TITLE>A Servlet</TITLE></HEAD>
    "
                        + "  <BODY>
    "
                        + "    This is class a, using the GET method
    "
                        + "  </BODY>
    " + "</HTML>
    " + "
    " ;
    
                outputStream.write(str.getBytes());
                    socket.close();
            }
    
    }
    }

      这一次只有Server...点击浏览器看看获取到什么...很显然,只要不断地修改HTML里面的内容,我们就能控制浏览器的展示效果(尽管略显2B。。。)

      ServerSocket与Socket的简单测试到这里了就结束了,通过JDK_API可以看到这货比想象中的要复杂得多...管他呢,以后遇见再说吧

    tomcat_1.socket简单的测试.zip

    第一章 一个简单的web服务器

    1.服务器或者说互联网究竟是什么,说不清楚,不过其工作形式就是资源的交换,而资源又有两种,1种为静态资源,比如各种视屏,文件,1种为动态资源或者称之为服务...
    2.将输入流封装为request,将输出流封装为response
    3.serversocket/socket与http协议
    以上就是我对第一章内容的总结

  • 相关阅读:
    10月27日PHP加载类、设计模式(单例模式和工厂模式)、面向对象的六大原则
    数据解析2:JSON解析(2)
    数据解析2:JSON解析(1)
    数据解析1:XML解析(3)
    数据解析1:XML解析(2)
    数据解析1:XML解析(1)
    设计模式4:装饰模式(1)
    设计模式3:模板模式(1)
    设计模式2:工程模式(1)
    设计模式1:单例模式(1)
  • 原文地址:https://www.cnblogs.com/liuCy/p/4018333.html
Copyright © 2011-2022 走看看