浏览器跟服务器的通信
最近看了不少socket通信的文章。什么BIO,NIO,AIO….
于是就想来个实践,一般的的demo 都是写个server,再写个client
但是,毕竟lz干的是烂大街的web开发
就想,既然bs架构中浏览器其实是充当了客户端,那么能不能把浏览器当做客户端实现socket通信?
毕竟tomcat其实就是功能做的也就是一个复杂一点的服务。。
经过实践发现还真可以,不过要通过http协议。。
(此文参考让浏览器可以访问我们的socket服务 (http协议入门))
客户端响应
浏览器创建连接时,让服务端响应一段文字
创建Request类处理http的请求
package HttpSocket;
/**
* Created by zhang on 2018/1/30.
*/
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* 接受HTTP请求
*/
public class Request {
// 用来保存输入流对象
private InputStream inputStream;
// 从输入流中每次读取的字节长度
private int bufferLength = 1024;
/**
* 构造函数
* @param inputStream
*/
public Request(InputStream inputStream) {
this.inputStream = inputStream;
}
/**
* 读取内容 返回字符串
* @return
* @throws IOException
*/
public String readHtml() throws IOException {
BufferedInputStream bufferedInputStream = new BufferedInputStream(this.inputStream);
byte[] buffer = new byte[this.bufferLength];
StringBuilder stringBuilder = new StringBuilder();
int len = 0;
while (true){
len = bufferedInputStream.read(buffer);
stringBuilder.append(new String(buffer,0,len));
if (len <= 0 || len<this.bufferLength){
break;
}
}
return stringBuilder.toString();
}
}
类中有两个方法,一个用来接受输入流对象,另一个用来读取内容。
socket服务端
package HttpSocket;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created by zhang on 2018/1/30.
*/
public class MainServer {
public static void main(String[] args) throws IOException {
// 服务端创建一个监听
ServerSocket serverSocket = new ServerSocket(9000);
// 监听客户端连接,方便起见不用多线程
Socket socket = serverSocket.accept();
// 要想获取客户端发送过来的内容,就要得到 InputStream类 的输入流对象
InputStream inputStream = socket.getInputStream();
//==========使用自定义的http处理的相关类===========//
Request request = new Request(inputStream);
System.out.println(request.readHtml());
socket.close();
}
}
运行socket服务端,然后浏览器访问http://localhost:9000,
Request对象 读取到的内容 会在控制台打印
"C:\Program Files\Java\jdk1.8.0_73\bin\java" "-javaagent:C:\Program Files\idea\lib\idea_rt.jar=55530:C:\Program Files\idea\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_73\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\rt.jar;E:\product\zhang123\Excercise\target\classes;E:\JavaWork\mvn\junit\junit\4.12\junit-4.12.jar;E:\JavaWork\mvn\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" HttpSocket.MainServer
GET / HTTP/1.1
Host: localhost:9000
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: ims_language=en
Process finished with exit code 0
这就是一个http请求
给浏览器响应内容
package HttpSocket;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* Created by zhang on 2018/1/30.
*/
public class Response {
private OutputStream outputStream;
public Response(OutputStream outputStream){
this.outputStream = outputStream;
}
public void writeHtml(String html) throws IOException {
html = "http/1.1 200 ok\n"
+"\n\n"
+html;
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(this.outputStream);
bufferedOutputStream.write(html.getBytes());
bufferedOutputStream.close();
}
}
在writeHtml()方法中,拼装一个符合http协议响应格式的字符串(这个也不全,http协议的东西挺繁杂,但有这个头就能识别,不然内容不会被浏览器解析识别)。
package HttpSocket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created by zhang on 2018/1/30.
*/
public class MyServer {
public static void main(String[] args) throws IOException {
// 服务端创建一个监听
ServerSocket serverSocket = new ServerSocket(9000);
// 监听客户端连接,暂时不用多线程
Socket socket = serverSocket.accept();
// 获取客户端发送过来的内容,得到 InputStream类 的输入流对象
InputStream inputStream = socket.getInputStream();
//==========使用自定义的http处理的相关类===========//
Request request = new Request(inputStream);
System.out.println(request.readHtml());
// 给客户端发送数据,就要得到
OutputStream outputStream = socket.getOutputStream();
Response response = new Response(outputStream);
response.writeHtml("this is my server");
// 关闭
inputStream.close();
outputStream.close();
socket.close();
}
}
socket服务端代码,向客户端输出了z字符串“this is my server”
运行这个服务端,再访问http://localhost:9000
页面上就会显示字符串