章前准备
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发回车(\r\n,\r\n)就可以获取响应,也许这就是他的结束标识
 */
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=='\r'&&flag==true){
                        break;
                    }
                    if(i=='\n'){
                        flag=true;
                    }else{
                        flag=false;
                    }
                    
                    System.out.print((char)i);
                }
                
                //发送回应
                OutputStream outputStream = socket.getOutputStream();
            String str = "HTTP/1.1 200 OK\n"
                    + "Server: Apache-Coyote/1.1\n"
                    + "Content-Type: text/html\n"
                    + "Transfer-Encoding: chunked\n"
                    + "Date: Wed, 29 Oct 2014 06:08:32 GMT\n"
                    + "\n"
                    + "bb\n"
                    + "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"
                    + "<HTML>\n" + "  <HEAD><TITLE>A Servlet</TITLE></HEAD>\n"
                    + "  <BODY>\n"
                    + "    This is class a, using the GET method\n"
                    + "  </BODY>\n" + "</HTML>\n" + "\n" ;

            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协议
以上就是我对第一章内容的总结

posted on 2014-10-11 09:32  Glimis  阅读(206)  评论(0编辑  收藏  举报