- 服务器的安装和配置(了解)
- 服务器和MyEclipse结合(了解)
- 服务器部署项目(掌握)
- Http协议格式(掌握)
优点:减少客户端的维护成本,无需客户端安装通过浏览器直接请求使用
缺点:加大了服务器端的压力
优点:核心运行在客户端对服务器端压力较小
缺点:核心代码在客户端需要维护并解决安全性
概念
或者是用于服务器系统的电脑
访问
TCP进行数据发送接收基础代码
//客户端socket
public class ClientSocket {public static void main(String[] args) throws Exception {//创建客户端服务指定连接ip与端口Socket s = new Socket("192.168.0.101", 8888);//获取输出流对象OutputStream os = s.getOutputStream();//使用输出流对象将数据发送至服务器端os.write("abcdefg".getBytes());os.flush();//关闭客户端服务s.close();}
}
//服务器端Socket
public class ServiceSocket {public static void main(String[] args) throws Exception {ServerSocket ss=new ServerSocket(8888);//通过阻塞方法获取连接的客户端对象Socket s = ss.accept();//获取输入流InputStream is = s.getInputStream();byte [] b=new byte[1024];int len =0;//读取客户端发送信息并打印while((len=is.read(b))!=-1){System.out.println(new String(b,0,len));}s.close();ss.close(); }
}
超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。
http是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII码形式给出;而消息内容则具有一个类似MIME的格式。这个简单模型是早期Web成功的有功之臣,因为它使得开发和部署是那么的直截了当。
http是应用层基于请求与响应的无状态传输协议
HTTP是一个客户端终端(用户)和服务器端(网站)请求和应答的标准(TCP)。通过使用网页浏览器、网络爬虫或者其它的工具,客户端发起一个HTTP请求到服务器上指定端口(默认端口为80)。我们称这个客户端为用户代理程序(user agent)。应答的服务器上存储着一些资源,比如HTML文件和图像。我们称这个应答服务器为源服务器(origin server)。在用户代理程序和源服务器中间可能存在多个“中间层”,比如代理服务器、网关或者隧道(tunnel)。
尽管TCP/IP协议是互联网上最流行的应用,HTTP协议中,并没有规定必须使用它或它支持的层。事实上,HTTP可以在任何互联网协议上,或其他网络上实现。HTTP假定其下层协议提供可靠的传输。因此,任何能够提供这种保证的协议都可以被其使用。因此也就是其在TCP/IP协议族使用TCP作为其传输层。
通常,由HTTP客户端发起一个请求,创建一个到服务器指定端口(默认是80端口)的TCP连接。HTTP服务器则在那个端口监听客户端的请求。一旦收到请求,服务器会向客户端返回一个状态,比如"HTTP/1.1 200 OK",以及返回的内容,如请求的文件、错误消息、或者其它信息。
http协议可以理解为底层使用tcp协议,当浏览器发起请求时会建立连接,当服务器响应后就会断开本次连接(每次输入网址发送请求都会建立一起连接,服务器会根据本次请求进行响应后结束连接)
HTTP是基于客户/服务器模式,且面向连接的。典型的HTTP事务处理有如下的过程:
(1)客户与服务器建立连接;
(2)客户向服务器提出请求;
(3)服务器接受请求,并根据请求返回相应的文件作为应答;
(4)客户与服务器关闭连接。
客户与服务器之间的HTTP连接是一种一次性连接,它限制每次连接只处理一个请求,当服务器返回本次请求的应答后便立即关闭连接,下次请求再重新建立连接。这种一次性连接主要考虑到WWW服务器面向的是Internet中成干上万个用户,且只能提供有限个连接,故服务器不会让一个连接处于等待状态,及时地释放连接可以大大提高服务器的执行效率。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OOT2tThP-1678210162291)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kXaLlltB-1678210162293)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
请求行
提交方式
提交的路径
协议版本
请求头
空行
请求体
使用tcp模拟http发送请求并接受请求服务器返回的结果
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;public class TcpSendHttp {public static void main(String[] args) throws Exception {//书写tcp客户端 连接指定服务器端Socket s=new Socket("220.181.38.149", 80);OutputStream os = s.getOutputStream();//通过输出流输出请求格式对应的字符串os.write("GET / HTTP/1.1\n".getBytes());//设置User-Agent 告诉指定服务器 我是个浏览器os.write("User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36".getBytes());os.write("\n\n".getBytes());//获取服务器返回的数据InputStream is = s.getInputStream();//尽量不要写循环 可能无法结束byte b[]=new byte[2048];int len = is.read(b);System.out.println(new String(b,0,len));s.close(); }
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rLkPtr7Q-1678210162295)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-19551BAO-1678210162298)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
使用tcp协议处理浏览器http发送的请求并响应数据
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class TcpGetHttp {public static void main(String[] args) throws Exception {//创建tcp服务器端 监听端口ServerSocket ss=new ServerSocket(10086);//获取客户端连接while(true){Socket s = ss.accept();InputStream is = s.getInputStream();//获取客户端浏览器请求的数据//转换为字符流InputStreamReader isr=new InputStreamReader(is);//转换字符高效流就是为了按行读取BufferedReader br=new BufferedReader(isr);//如果使用while会使页面一直等待//所以我们只获取请求第一行String line= br.readLine();System.out.println("浏览器请求:"+line);//http协议基于请求与响应 //所以服务器需要返回响应数据//浏览器页面第一次请求时会额外请求favicon.ico//作为当前服务器的图标 如果没有可能报错//返回响应数据OutputStream os = s.getOutputStream();os.write("HTTP/1.1 200 OK\nContent-Type: text/html; charset=utf-8 \r\n\r\n请求成功".getBytes());//防止乱码 添加返回为html 编码为utf-8s.close();}}
}
使用Socket请求百度获取百度响应信息
//客户端socket
public class ClientSocket {public static void main(String[] args) throws Exception {// 创建客户端服务指定连接ip与端口Socket s = new Socket("www.baidu.com", 80);// 获取输出流对象OutputStream os = s.getOutputStream();InputStream is = s.getInputStream();// 使用输出流对象将数据发送至服务器端os.write("GET / HTTP/1.1\n".getBytes());os.write("\r\n".getBytes());os.flush();byte[] b=new byte[1024];int len=0;while((len=is.read(b))!=-1){System.out.println(new String(b,0,len));}// 关闭客户端服务s.close();}
}
百度响应信息
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 14615
Content-Type: text/html
Date: Mon, 09 Aug 2021 02:53:28 GMT
P3p: CP=" OTI DSP COR IVA OUR IND COM "
P3p: CP=" OTI DSP COR IVA OUR IND COM "
Pragma: no-cache
Server: BWS/1.1
Set-Cookie: BAIDUID=2891F7401E9F30AC9014BC5F4CF3FE8E:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BIDUPSID=2891F7401E9F30AC9014BC5F4CF3FE8E; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1628477608; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BAIDUID=2891F7401E9F30ACD654ACBAE3F7E218:FG=1; max-age=31536000; expires=Tue, 09-Aug-22 02:53:28 GMT; domain=.baidu.com; path=/; version=1; comment=bd
Traceid: 162847760828380290667205192330022957930
Vary: Accept-Encoding
X-Frame-Options: sameorigin
X-Ua-Compatible: IE=Edge,chrome=1
.....
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Ga6TwHJ-1678210162301)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
//使用tcp处理http请求并响应数据
public class TcpResponse {// 使用tcp socket介绍浏览器发生的http请求 并解析请求中的数据// 根据http响应的语法 将数据发送至浏览器显示// 客户端在浏览器输入网址 输入请求数据// localhost:8888/login?username=zhangsan&password=123456// 根据输入的数据判断账号密码 返回 登录成功 或 登录失败public static void main(String[] args) throws Exception {// 创建sokect服务器监听指定端口ServerSocket ss = new ServerSocket(8888);while (true) {// 获取客户端连接对象Socket s = ss.accept();// 获取输入流 读取客户端发送的请求信息// 使用转换流与高效流读取InputStream is = s.getInputStream();// 使用转换流将字节流换行为字符流InputStreamReader isr = new InputStreamReader(is);// 创建字符高效流BufferedReader br = new BufferedReader(isr);// 如果使用while可能导致一直读取// 在获取请求信息时 实际基本只有第一行数据有用 所以获取第一行数据即可String readLine = br.readLine();// 解析请求数据获取请求信息// 使用空格获取中间数据String[] split = readLine.split(" ");System.out.println(split[1]);String data = split[1];// 判断是否包含? 判断请求格式是否符合标准String msg = "";if (data.contains("?")) {// 继续截取String[] dataArr = data.split("\\?");System.out.println("请求的服务地址为:" + dataArr[0]);HashMap parseSring = parseSring(dataArr[1]);System.out.println("请求的数据为:" + parseSring);if(dataArr[0].equals("/login")){if(parseSring.get("username").equals("zhangsan")&&parseSring.get("password").equals("123456")){msg="登录成功";}else{msg="登录失败";}}else{msg="无法处理该请求";}} else {msg = "请输入正确的请求格式";}// 获取输出流OutputStream os = s.getOutputStream();// 根据http响应格式 响应客户端的请求os.write("HTTP/1.1 200 OK\n".getBytes());// 设置页面解析数据的编码格式os.write("Content-Type: text/html ;charset=utf-8\n".getBytes());os.write("\r\n".getBytes());os.write(msg.getBytes());os.flush();os.close();// 关闭流br.close();s.close();}// ss.close();}//将参数字符串转换为map集合public static HashMap parseSring(String str){HashMap values=new HashMap<>();String[] split = str.split("&");for (String string : split) {String[] split2 = string.split("=");values.put(split2[0],split2[1]);}return values;}
}
注意:
1.使用tcp协议处理http请求时 本质还是通过io流进行数据的发送与返回
2.因为http协议在1.1之后一次连接可以多次请求(长连接),所以不能使用while读取 否则会一直进行读取操作(等待客户端发送信息),不会继续进行,所以一般只读取首行即可
3.书写服务器接收数据后必须书写响应数据(按照http协议响应的格式),否则浏览器会一直等待,直至超时,显示请求失败(因为没有接收到服务器的响应信息,默认理解为服务器找不到)
4.如果返回的数据存在中文,那么可能出现乱码,可以在相应的字符串中添加对应的编码集
os.write(“Content-Type: text/html ;charset=utf-8\n”.getBytes());
5.建议使用无痕浏览器打开,否则可能出现修改后页面不更改
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;//使用tcp处理http请求并响应数据
public class TcpResponseHtml {// 使用tcp socket介绍浏览器发生的http请求 并解析请求中的数据// 根据http响应的语法 将数据发送至浏览器显示// 客户端在浏览器输入网址 输入请求数据// localhost:8888/login?username=zhangsan&password=123456// 根据输入的数据判断账号密码 返回 登录成功 或 登录失败public static void main(String[] args) throws Exception {// 创建sokect服务器监听指定端口ServerSocket ss = new ServerSocket(8888);while (true) {// 获取客户端连接对象Socket s = ss.accept();// 获取输入流 读取客户端发送的请求信息// 使用转换流与高效流读取InputStream is = s.getInputStream();// 使用转换流将字节流换行为字符流InputStreamReader isr = new InputStreamReader(is);// 创建字符高效流BufferedReader br = new BufferedReader(isr);// 如果使用while可能导致一直读取// 在获取请求信息时 实际基本只有第一行数据有用 所以获取第一行数据即可String readLine = br.readLine();String[] split = readLine.split(" ");String data = split[1];// 获取输出流OutputStream os = s.getOutputStream();// 根据http响应格式 响应客户端的请求os.write("HTTP/1.1 200 OK\n".getBytes());// 设置页面解析数据的编码格式os.write("Content-Type: text/html ;charset=utf-8\n".getBytes());os.write("\r\n".getBytes());// 创建返回页面的文件对象File path = new File("D:/eclipse/work/Day0809/src/com/yunhe/tcpTOhttp");File f = new File(path, data);// 读取文件将文件写入响应中try {FileInputStream fis = new FileInputStream(f);byte b[] = new byte[1024];int len = 0;while ((len = fis.read(b)) != -1) {os.write(b, 0, len);}fis.close();} catch (FileNotFoundException e) {System.out.println(data+"文件不存在");}os.flush();os.close();// 关闭流br.close();s.close();}}
}
1.使用位置不同
http是应用层协议,tcp是传输层协议(tcp更底层)
http针对于万维网数据请求与响应,tcp就是直连数据传输
2.连接方式不同
http基于请求与响应进行连接,tcp经过三次握手建立连接
3.同一个连接中数据交互次数不同
http请求一次建立一次连接(1.0),在1.1之后可以多次 但是一定时间没有请求则断开,tcp可以在连接期间无限制的进行数据的交互,直至主动断开
4.数据交互方式不同
http在连接时会将数据书写在请求中,服务器通过解析请求获取数据
tcp在建立连接后直接进行数据的交互
解决方案
杀死现有的程序
修改tomcat的端口号
conf/server.xml
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WLzCnkWD-1678210162303)(asseits/image-20200318155053556.png)]
bin:该目录下存放的是二进制可执行文件,如果是安装版,那么这个目录下会有两个exe文件:tomcat8.exe、tomcat8w.exe,前者是在控制台下启动Tomcat,后者是弹出UGI窗口启动Tomcat;如果是解压版,那么会有startup.bat和shutdown.bat文件,startup.bat用来启动Tomcat,但需要先配置JAVA_HOME环境变量才能启动,shutdawn.bat用来停止Tomcat;
conf:这是一个非常非常重要的目录,这个目录下有四个最为重要的文件:
server.xml:配置整个服务器信息。例如修改端口号,添加虚拟主机等;下面会详细介绍这个文件;
tomcatusers.xml:存储tomcat用户的文件,这里保存的是tomcat的用户名及密码,以及用户的角色信息。可以按着该文件中的注释信息添加tomcat用户,然后就可以在Tomcat主页中进入Tomcat Manager页面了;
web.xml:部署描述符文件,这个文件中注册了很多MIME类型,即文档类型。这些MIME类型是客户端与服务器之间说明文档类型的,如用户请求一个html网页,那么服务器还会告诉客户端浏览器响应的文档是text/html类型的,这就是一个MIME类型。客户端浏览器通过这个MIME类型就知道如何处理它了。当然是在浏览器中显示这个html文件了。但如果服务器响应的是一个exe文件,那么浏览器就不可能显示它,而是应该弹出下载窗口才对。MIME就是用来说明文档的内容是什么类型的!
context.xml:对所有应用的统一配置,通常我们不会去配置它。
lib:Tomcat的类库,里面是一大堆jar文件。如果需要添加Tomcat依赖的jar文件,可以把它放到这个目录中,当然也可以把应用依赖的jar文件放到这个目录中,这个目录中的jar所有项目都可以共享之,但这样你的应用放到其他Tomcat下时就不能再共享这个目录下的Jar包了,所以建议只把Tomcat需要的Jar包放到这个目录下;
logs:这个目录中都是日志文件,记录了Tomcat启动和关闭的信息,如果启动Tomcat时有错误,那么异常也会记录在日志文件中。
temp:存放Tomcat的临时文件,这个目录下的东西可以在停止Tomcat后删除!
webapps:存放web项目的目录,其中每个文件夹都是一个项目;如果这个目录下已经存在了目录,那么都是tomcat自带的。项目。其中ROOT是一个特殊的项目,在地址栏中没有给出项目目录时,对应的就是ROOT项目。http://localhost:8080/examples,进入示例项目。其中examples就是项目名,即文件夹的名字。
work:运行时生成的文件,最终运行的文件都在这里。通过webapps中的项目生成的!可以把这个目录下的内容删除,再次运行时会生再次生成work目录。当客户端用户访问一个JSP文件时,Tomcat会通过JSP生成Java文件,然后再编译Java文件生成class文件,生成的java和class文件都会存放到这个目录下。
LICENSE:许可证。
NOTICE:说明文件。
测试:
主机IP地址/localhost:端口号
端口号修改之后,需要重启服务器
tomcat默认的端口号是8080,我们的操作系统默认的端口是80,可以省略:80
将我们之前写的程序,放webapps下了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bOdSf8r0-1678210162306)(asseits/image-20200318161506952.png)]
访问的时候
localhost:端口号/网站程序名
注意事项:
目前一般人不会碰到
假如你碰到了,
cmd-》netstat -ano去查看8080端口被哪个程序占用了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zPaTV3RQ-1678210162309)(asseits/image-20200318162331092.png)]
Ctrl+Shift+Esc
假设不是java程序占用了,可以结束掉
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IW2o76GJ-1678210162311)(asseits/image-20200318162412514.png)]
在启动Tomcat之前,我们必须要配置环境变量
JAVA_HOME:必须先配置JAVA_HOME,因为Tomcat启动需要使用JDK;
startup.bat会调用catalina.bat,而catalina.bat会调用setclasspath.bat,setclasspath.bat会使用JAVA_HOME环境变量,所以我们必须在启动Tomcat之前把JAVA_HOME配置正确。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ysPv86Dw-1678210162312)(asseits/image-20200318155358921.png)]
Tomcat的安装路径;
CLASSPATH:也可以先不配置,重点是JAVA_HOME这个变量的配置。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kRzNmzm4-1678210162313)(asseits/image-20200318155618533.png)]
启动Tomcat
1.在tomcat的安装路径下,有startup.bat文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WQLgTqK6-1678210162314)(asseits/image-20200318155916935.png)]
访问测试:http://localhost:8080/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oIKFwwL6-1678210162315)(asseits/image-20200318155852810.png)]
2.启动方式2
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-22qeyqDk-1678210162316)(asseits/image-20200318160204089.png)]
3.启动方式3
cmd->
cd 你的tomcat目录\bin 这个路径
输入catalina run
会显示环境变量的依赖:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6JT98Aee-1678210162317)(asseits/image-20200318160550082.png)]
关闭:
因为已经关闭了,所以报错。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sZoabHJc-1678210162318)(asseits/image-20200318160110297.png)]
a)第一种方式:直接在webapps下放我们的网站目录;
打一个war包的方式放到webapps下,这个war包会自动解压;
b)第二种方式:配置Server.xml文件
docBase:表示网站的实际路径path:表示外部的url访问的路径
c)第三种方式:在conf下的Catalina下的localhost增加一个url.xml的文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gvYuiiLU-1678210162319)(asseits/image-20200319145402134.png)]
参考配置:
并且第4种方式,如果url发生变更,不需要重启服务器,只用修改文件名即可,也就是说文件名和url一致的。
动态web项目目录介绍
静态WEB项目结构
解决idea启动tomcat控制台中文乱码
2318)]
a)第一种方式:直接在webapps下放我们的网站目录;
打一个war包的方式放到webapps下,这个war包会自动解压;
b)第二种方式:配置Server.xml文件
docBase:表示网站的实际路径path:表示外部的url访问的路径
c)第三种方式:在conf下的Catalina下的localhost增加一个url.xml的文件
[外链图片转存中…(img-gvYuiiLU-1678210162319)]
参考配置:
并且第4种方式,如果url发生变更,不需要重启服务器,只用修改文件名即可,也就是说文件名和url一致的。
动态web项目目录介绍
静态WEB项目结构
解决idea启动tomcat控制台中文乱码
修改idea显示编码,windows默认用gbk所以idea显示默认为GBK编码,在Help→Edit custom vm options 添加 -Dfile.encoding=UTF-8