java编写访问网页服务器,使用ServerSocket,模拟B/S服务器,及使用浏览器,访问自己本地的网页…

最近学到了网络编程,有个练习:

模拟BS服务器

模拟网站服务器,使用浏览器访问自己编写的服务端程序,查看网页效果。

踩了两个坑,就是:

①HTTPS,不能用这个协议,来访问,因为这玩意是加密了的,一开始我还以为它传的不是UTF-8,因为我用的IDEA,默认UTF-8,我还用InputStreamReader去转换,但是发现没法,后来,突然想起了,HTTPS是加密的,然后用HTTP试了,就可以了。

②网站输入的地址,可以用绝对路径,也可用相对路径,相对路径是相对于我们写的服务端类的项目位置比如我的服务端: 我们的地址就要这样输入:

http://localhost:8888/Advanced/src/Net/BSTCP/web/index.html

5bbf0d9b3f9430ee7feb9afc7c86c72a.png

注意事项:

①这个是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());

写代码思路

客户端是网站,我们只写服务端

需要写两个服务端,一个是向客户端发送html代码,一个是发送图片

建立连接时,需要使用HTTP协议,而不能使用HTTPS协议,这个协议被加密了,所以客户端只能输出加密的请求头。

服务端的执行步骤:

先创建ServerSocket,监听请求,接收到了,就使用accept( )捕获。

利用网络输入流,读取客户端请求头,然后获取Get请求,其中的文件地址。

处理地址格式

使用本地文件流,读取文件,并向客户端输出

在创建一个传输照片的服务端,与传输html的服务端代码几乎一样,差别在于,传输照片服务端,要一直监听请求,因为他传输的不是一张照片

优化:

使用多线程,加快传输效率

下面放出全部代码:

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();

}

}

}

原文链接:https://blog.csdn.net/weixin_30923011/article/details/119584623

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享