关于java:使用ServerSocket模拟BS服务器及使用浏览器访问自己本地的网页

2次阅读

共计 3460 个字符,预计需要花费 9 分钟才能阅读完成。

最近学到了网络编程,有个练习:
模仿 BS 服务器 模仿网站服务器,应用浏览器拜访本人编写的服务端程序,查看网页成果。
踩了两个坑,就是:

  • ①HTTPS,不能用这个协定,来拜访,因为这玩意是加密了的,一开始我还认为它传的不是 UTF-8,因为我用的 IDEA,默认 UTF-8,我还用 InputStreamReader 去转换,然而发现没法,起初,忽然想起了,HTTPS 是加密的,而后用 HTTP 试了,就能够了。
  • ②网站输出的地址,能够用绝对路径,也可用相对路径,相对路径是 绝对于咱们写的服务端类的我的项目地位 比方我的服务端:咱们的地址就要这样输出:
  • http://localhost:8888/Advanced/src/Net/BSTCP/web/index.html

注意事项:

  • ①这个是 HTTP 的响应头是固定的格局,须要留神:
    Http 响应头要固定:
  • ②谷歌看不了,倡议换其余浏览器看。

    // 写入 HTTP 协定响应头, 固定写法
      os.write("HTTP/1.1 200 OK\r\n".getBytes());
      os.write("Content‐Type:text/html\r\n".getBytes());
      // 必须要写入空行, 否则浏览器不解析
      os.write("\r\n".getBytes());

写代码思路

  1. 客户端是网站,咱们只写服务端
  2. 须要写两个服务端,一个是向客户端发送 html 代码,一个是发送图片
  3. 建设连贯时,须要应用 HTTP 协定,而不能应用 HTTPS 协定,这个协定被加密了,所以客户端只能输入加密的申请头。
  4. 服务端的执行步骤:

    1. 先创立 ServerSocket,监听申请,接管到了,就应用 accept()捕捉。
    2. 利用网络输出流,读取客户端申请头,而后获取 Get 申请,其中的文件地址。
    3. 解决地址格局
    4. 应用本地文件流,读取文件,并向客户端输入
    5. 在创立一个传输照片的服务端,与传输 html 的服务端代码简直一样,差异在于,传输照片服务端,要始终监听申请,因为他传输的不是一张照片
    6. 优化:
      应用多线程,放慢传输效率

上面放出全副代码:
html 服务端:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//http://localhost:8888/Advanced/src/Net/BSTCP/web/index.html HTTP/1.1
// 不能应用 https,加密协议
public class Server {public static void main(String[] args) throws IOException {System.out.println("服务端启动,期待连贯。。。。");
        // 创立一个服务器 ServerSocket, 和零碎要指定的端口号
        ServerSocket server = new ServerSocket(8888);
        // 应用 accept 办法获取到申请的客户端对象(浏览器)
        Socket socket = server.accept();
        // 应用 Socket 对象中的办法 getInputStream, 获取到网络字节输出流 InputStream 对象
        InputStream is = socket.getInputStream();

        // 输入客户端的申请
        /*byte[] bytes = new byte[1024];
        int len = is.read(bytes);
        System.out.println(new String(bytes,0,len));
        System.out.println("cao");*/

        // 把 is 字节流,转换成字符流,并且应用缓冲流读取
        BufferedReader br = new BufferedReader(new InputStreamReader(is));

        // 读取第一行 GET 申请的内容
        String s = br.readLine();
        // 按空格把它离开
        String[] s1 = s.split(" ");
        // 把后面的 "/" 给排除,应用字符串的截取
        String path = s1[1].substring(1);
        System.out.println(path);

        // 创立一个 fis 流,读取本地的 index.html 文件
        FileInputStream fis = new FileInputStream(path);
        // 获取网络输入流 OutputStream,向客户端输入页面
        OutputStream os = socket.getOutputStream();

        // 写入 HTTP 协定响应头, 固定写法
        os.write("HTTP/1.1 200 OK\r\n".getBytes());
        os.write("Content‐Type:text/html\r\n".getBytes());
        // 必须要写入空行, 否则浏览器不解析
        os.write("\r\n".getBytes());

        // 向客户端输入
        byte bytes[] = new byte[1024];
        int len = 0;
        while((len = fis.read(bytes))!=-1){os.write(bytes);
        }
        // 敞开资源
        fis.close();
        br.close();
        socket.close();}
}

照片服务端

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ImageServer {public static void main(String[] args) throws IOException {System.out.println("服务端启动,期待连贯。。。。");
        // 创立一个服务器 ServerSocket, 和零碎要指定的端口号
        ServerSocket server = new ServerSocket(8888);
        while (true){// 应用 accept 办法获取到申请的客户端对象(浏览器)
            Socket socket = server.accept();
            // 应用 Socket 对象中的办法 getInputStream, 获取到网络字节输出流 InputStream 对象
            InputStream is = socket.getInputStream();

            // 输入客户端的申请
            /*byte[] bytes = new byte[1024];
            int len = is.read(bytes);
            System.out.println(new String(bytes,0,len));
            System.out.println("cao");*/

            // 多线程,放慢传输速度
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try{
                        // 把 is 字节流,转换成字符流,并且应用缓冲流读取
                        BufferedReader br = new BufferedReader(new InputStreamReader(is));

                        // 读取第一行 GET 申请的内容
                        String s = br.readLine();
                        // 按空格把它离开
                        String[] s1 = s.split(" ");
                        // 把后面的 "/" 给排除,应用字符串的截取
                        String path = s1[1].substring(1);
                        System.out.println(path);

                        // 创立一个 fis 流,读取本地的 index.html 文件
                        FileInputStream fis = new FileInputStream(path);
                        // 获取网络输入流 OutputStream,向客户端输入页面
                        OutputStream os = socket.getOutputStream();

                        // 写入 HTTP 协定响应头, 固定写法
                        os.write("HTTP/1.1 200 OK\r\n".getBytes());
                        os.write("Content‐Type:text/html\r\n".getBytes());
                        // 必须要写入空行, 否则浏览器不解析
                        os.write("\r\n".getBytes());

                        // 向客户端输入
                        byte bytes[] = new byte[1024];
                        int len = 0;
                        while((len = fis.read(bytes))!=-1){os.write(bytes);
                        }
                        // 敞开资源
                        fis.close();
                        br.close();
                        socket.close();}catch (IOException e){e.printStackTrace();
                    }
                }
            }).start();}

    }
}
正文完
 0