模拟B,S服务器

最近学到了网络编程,有个练习:
模拟B\S服务器 模拟网站服务器,使用浏览器访问自己编写的服务端程序,查看网页效果。
踩了两个坑,就是:

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

(15)4L~J0~R(92LYVW27ZTY.png

注意事项:

  • ①这个是HTTP的响应头是固定的格式,需要注意:
    Http响应头要固定:
  • ②谷歌看不了,建议换其他浏览器看。
    1
    2
    3
    4
    5
    // 写入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. 优化:
      <font color=red>使用多线程,加快传输效率</font>

下面放出全部代码:
html服务端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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();

}
}

照片服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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();


}

}
}
# 相关文章
  1.IO流为什么要边读编写
评论