服务器端的代码如下: (初步代码)
package WEBjava.B_S_webMod;
import java.io.*;
import java.net.*;
public class B_S_server_TCP {
public static void main(String[] args) throws Exception{
//创建一个服务器ServerSocket,并且和系统要指定的端口号
ServerSocket server = new ServerSocket(8989);
//使用accept()方法来监听并且获取到请求的客户端对象(浏览器)的请求信息
Socket whichSocket = server.accept();
//使用Socket对象中的方法getInputStream(),获取网络字节输入流(准备把浏览器发来的请求输入到程序中)
InputStream itps = whichSocket.getInputStream();
//使用网络字节输入流InputStream类的对象中的方法read()来读取客户端(浏览器)发来的信息
byte[] bytes = new byte[1024];
int len = 0;
while((len = itps.read(bytes)) != -1 ){
System.out.println(new String(bytes,0,len));
}
whichSocket.close();
server.close();
}
}
接下来运行服务器代码,在浏览器地址栏输入http://127.0.0.1:8989/WEBjava/B_S_webMod/web/index.html
运行结果如下图,
此时证明这个URL是可以找到指定服务器的
之后接着补充代码,实现网页回传功能,完整版代码如下
package WEBjava.B_S_webMod;
/**
* 这是一个浏览器和服务器的网络编程模型。客户端是任意的浏览器,就不用写了,但是服务器要有所变化
当浏览器在地址栏输入URL时,会向服务器发出请求数据,服务器收到数据后就要处理数据并且向浏览器返回网页文件
因此服务器这边要先把写好的网页文件准备好(就是把网页文件夹复制到同一个包下)
接下来开始创建BS版本的TCP服务器
**/
import java.io.*;
import java.net.*;
public class B_S_server_TCP {
public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket(8989);
Socket whichSocket = server.accept();
InputStream itps = whichSocket.getInputStream();
/**
* 在浏览器的地址栏里输入URL: http://127.0.0.1:8989/WEBjava/B_S_webMod/web/index.html
因为是本机,所以是127.0.0.1 端口号 储存网页文件的目录
此时浏览器会发来http协议的请求报文
其中报文请求行为:GET /WEBjava/B_S_webMod/web/index.html HTTP/1.1
这也是最关键的一部分信息
*/
//那么实际上我们只需要获取到浏览器发来的请求行这一行数据就够了,其他行的信息也就不用读完
//所以把原本的上面的read()方法的代码删掉,重新写一个更加高效的代码
//把itps 这个网络字节输入流对象转换为字符缓冲输入流
BufferedReader br = new BufferedReader(new InputStreamReader(itps));
//把客户端请求信息的第一行读取出来,GET /WEBjava/B_S_webMod/web/index.html HTTP/1.1
String line = br.readLine()
//把读取出来的信息进行切割,只要中间部分, /WEBjava/B_S_webMod/web/index.html
String[] arr = line.split(" ");
//把路径前面的/去掉 进行截取 WEBjava/B_S_webMod/web/index.html
String htmlPath = arr[1].substring(1);
//创建一个本地字节输入流,构造方法中绑定要读取的html路径
FileInputStream fipts = new FileInputStream(htmlPath);
//使用Socket中的方法getOutputStream()获取网络字节输出流OutputStream对象
OutputStream otps = whichSocket.getOutputStream();
//接下来写下三行固定的代码 ~~~~~~这和Http协议相关
//1 写入HTTP协议的响应头,固定写法
otps.write("HTTP/1.1 200 OK\r\n".getBytes());
//2 写下服务器响应的第二行信息
otps.write("Content-Type:text/html\r\n".getBytes());
//3 必须写入空行 , 要不然浏览器不能解析
otps.write("\r\n".getBytes()) ;
//一读一写复制文件,把服务器读取的html文件回写到客户端
int len = 0 ;
byte[] bytes = new byte[1024];
while((len = fipts.read(bytes)) != -1){
otps.write(bytes,0,len);
}
//释放资源
fipts.close();
whichSocket.close();
server.close();
}
}
运行结果如下图:
问题解决:
思路1:因为一开始的代码运行结果是服务器端可以收到浏览器发来的请求,这说明找到到服务器而已
但完整版代码运行则出现系统找不到指定路径异常,这说明URL写错了,或者URL在被服务器程序分析时写错了
尝试1:再次检查服务器端解析请求信息的代码
检查完代码,在截取完路径htmlPath后添加了一行
System.out.println(htmlPath);
结果1:输出结果没有错误,浏览器URL输入什么路径,这边htmlPath也能正确提取路径
思路2:根据以上信息,推测应该是浏览器输入的URL路径本身出错
尝试2:这次把URL改成了
http://127.0.0.1:8989/E:/Java/testdemo/demo1/bin/WEBjava/B_S_webMod/web/index.html
原本是
http://127.0.0.1:8989/WEBjava/B_S_webMod/web/index.html
结果2:这次成功访问到了html页面文件了
解决完上述问题,又有新的问题:为啥一定要用绝对路径作为URL来访问才可以成功呢?
现实情况是不能让用户输入这么多内容的,如何才能使用相对的URL来访问呢?