Java搭建web服务器之Socket编程,更好的明白 Apache、Tomcat|新京葡萄官方网站

日期:2023-11-05 21:18 | 人气:

本文摘要:之前做web应用一直是在当地装个Apache、Tomcat之类的软件,然后把做好的网页文件放在他们的事情目录下(如Apache的htdocs),然后打开浏览器输入127.0.0.1或localhost就可以直接会见了,好神奇,可是为什么,怎么实现的呢,早就知道有Socket(套接字)这个工具,可之前就是没有把这两方面联合起来,今天我们就一起来看一看这究竟是为什么。

之前做web应用一直是在当地装个Apache、Tomcat之类的软件,然后把做好的网页文件放在他们的事情目录下(如Apache的htdocs),然后打开浏览器输入127.0.0.1或localhost就可以直接会见了,好神奇,可是为什么,怎么实现的呢,早就知道有Socket(套接字)这个工具,可之前就是没有把这两方面联合起来,今天我们就一起来看一看这究竟是为什么。有同学说还不懂Socket是什么,这工具很抽象,在盘算机网络原理里讲协议时才会看到,今天咱们完全忽略太严谨、学术的界说,就来看看Socket到底是什么。

想象一下,你把电脑的电源插在插座上,你的电脑就可以使用了,为什么?“这不是空话吗!”确实,咱们来想一下这个历程,你拿着插头插在了插座上,然后你的电脑和千里之外的供电厂就能“通信”了,把你的电脑想成是客户端,把千里之外的供电厂想成是服务器,通过插座和很长很长的线缆你们就可以勾结上了,那么Socket在这其中相当于什么呢?“插座!”没错,就是插座!对于我的电脑来说,我想让它通电事情,我只需要个插座就行了啊,什么插座是什么材质的,线缆是什么型号的,供电厂到底在什么经纬度,电力到底怎么传输,我管它干嘛呢,都跟我没关系!我只要知道我需要的不是整个世界,而是。一个插座!读到这里,想必同学已经对“插座”有了很森的明白了;再举一个例子,你和基友的电脑通过有线的方式连上了同一个路由器,这个时候你们就可以直接通过内网IP地址举行会见了,在这个历程中,谁人方方的接口(RJ45接口)就是“Socket”,横竖插上“Socket”就能用,我不用管到底通过Socket怎么能够实现通信。在盘算机编程的网络世界里,作为应用法式,我只需要一个“插座”就可以和任何服务器通信了,想想都有点小激动呢~~~接下来要讲的就是,电脑电源需要一个socket去插上,那么发电厂呢,也同样需要一个插座插上去来给你供电——也就是说,发电厂需要一个“插座”!。

空话,,,,没错,确实是这样,服务器端也需要一个“插座”,只不外它叫做ServerSocket(这看起来像是继续自Socket,我也不知道,待查)。有了“插座”(Socket)的观点之后,我们就可以愉快地让电脑(客户端)与发电厂(服务器)通信了。无论是客户端还是服务器,都需要Socket,鉴于咱们今天的题目是“搭建web服务器”,所以咱们接下来就来看一下怎么建立服务器的ServerSocket。

说道这里,有同学就会问到了,“岂非客户端不需要Socket吗?”,确实需要,因为我们是用浏览器会见本机IP“127.0.0.1”,所以客户端的Socket就由浏览器自己维护了,不需要咱们动手写的。“可是我还是不明确为什么在浏览器里输入127.0.0.1之后就可以看到我的网页了?求解释” 好,那咱们逐步来,先动手编写一个服务器端的ServerSocket吧啦啦啦~建立服务器端Socket的步骤如下:1、建立ServerSocket工具ServerSocket serverSocket = new ServerSocket(“80”); //这里只需要指明当前法式监听80号端口就可以了,至于为什么是80,因为我喜欢!“好蛮横。”因为我们要监听web请求,默认就是80号端口。

其实,1-1024端口被操作系统占用了,1025-65535的端口你随便用,只要不会和其他应用法式冲突就可以(别用什么类似3389这么常用的端口就好了。) 2、作为服务器,我要知道,我的使命就是要等候客户端发来请求,也就是客户端发来Socket,我首先要把它Hold住!Socket socket = serverSocket.accept(); //这里需要特别说明一下,accept方法比力特殊,它是一个阻塞方法(block method),因为只要它等不来客户端发来的请求(Socket),它就一直等下去而不会继续执行它下面的代码。唉,此等痴情人怎么跟我一样O(∩_∩)O 3、客户端要向我表明,给我发来情书,那我作为服务器只要获得它的输入就好了InputStream inputStream = socket.getInputStream(); //注意,客户端发来的表明信息都在socket内里,而不是serverSocket内里,这点要是弄错了,读不到情书内容,活该你只身。(我只有冷笑。

) 4、收到了情书,我好想知道内里究竟写了什么啊!迫!不!及!待! 好,开始剖析情书内容BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); //java包装类,只为读到写给我的情书,耶~ String line = “”; while ( (line = reader.readLine()) != null ){ System.out.println(line); } 5、组装前4步的代码,会要求try catch一下异常,正常捕捉就好 下面贴代码public class MultiWebServer { public static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(80); System.out.println("正在等候情书中..."); Socket socket = serverSocket.accept(); System.out.println("收到情书,我要开始剖析!"); InputStream inputStream = socket.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line = ""; while ( (line = reader.readLine()) != null ){ System.out.println(line); } } catch (Exception e) { e.printStackTrace(); } } } 好了,服务器端的代码咱们写完了,那接下来干啥?不知道。不外还记得适才提出的问题吗——“可是我还是不明确为什么在浏览器里输入127.0.0.1之后就可以看到我的网页了?”那就试试呗,看看咱们如果在浏览器里输入127.0.0.1或者localhost会怎么样首先必须把适才咱们编写的服务器端法式运行起来,然后再打开浏览器,记着,必须先运行服务器端法式,否则情书就发丢了。运行服务器端法式,如图:注意红圈中的两点:由于此时没有客户端发来情书,还记得适才的accept()阻塞方法吗,它就一直等啊等,等不来我还等,所以红圈中会显示“正在等候情书中…”;那么右面谁人箭头指向的是什么意思呢,一个红色停止的图标,也就是说,这个法式现在一直在执行着,没有竣事,就似乎死循环一样(固然这里绝对不是死循环,其实是阻塞,只是死的样子似乎死循环,一会咱们谈判到死循环的,别着急,早晚会死的)接下来打开浏览器,在地址栏输入127.0.0.1/index.html后回车,看看浏览器什么反映。

一段时间已往了,浏览器居然一点反映都没有,然后告诉我该页无法显示。我去。

岂非讲了这么多咱们就这么失败了吗,我哭。那就打开eclipse看一眼吧,看看服务器端有没有什么消息啊。打开服务器端一看,卧槽,瞬间世界向我问好了!注意看红笔标注,我收到了情书!我要开始剖析了!那到底情书里是什么内容,别问我,继续向下看。“好熟悉的一段报文,我们似乎在哪见过,还记得吗,那是一个春天,你刚发芽儿。

”没错,这就是盘算机网络原理讲的http请求报文。没有学过计网怎么办,没关系,看前两行(其实我们一会用到的也只有第一行而已),“我看到了index.html” 是的,这是适才我们在浏览器内里输入的地址;第二行,“我也看到了127.0.0.1”,是的,也是我们刚刚在浏览器内里输入的。

这说明晰什么?激动的我无法说出这到底说明晰什么,但想必读者你已经臆测出了什么。写到这里,作为服务器的我已经收到了从客户端发来的情书,那客户端(浏览器)为什么一点反映都没有呢,甚至过了一会就“该页无法显示”了。

因为啊,人家给你写了情书,你没回复人家,人家等了一会以为没戏了就伤心欲绝了!是啊,喜不喜欢人家都要和他说一声的,给他个回复,哪怕只说:“对不起,你是个好人。” 走神了吧?似乎说到自己了吧?回来吧,咱们现在的任务呢,就是怎么给人家个回复。怎么给,怎么给,怎么给。

快想快想,既然人家都指明晰想和127.0.0.1里的“index.html”表明,那固然就得由index.html来给他回复喽。怎么答,怎么答,怎么答。

快想快想,既然index.html是个文件,那我读出文件内容后直接发给客户端不就行了吗?可是用什么发?没错,是socket!我们用socket把文件的内容返回给客户端就好了。那么问题来了。

“说的很是好,关键是怎么做!”——首先怎么读出文件来?假定咱们的index.html在我电脑的E://课件/盘算机网络原理/实验/实验1/ 文件夹下,而且假定不会跨域会见,则:1、界说一个字符串,用来存咱们的事情目录String base_url = "E://课件/盘算机网络原理/实验/实验1/"; //这只是我本机的目录,至于到了你的电脑上,你可以自己更改 2、我怎么通过报文知道客户端要和index.html表明?看情书第一行 GET /index.html HTTP/1.1,所以只需要获取情书的第一行字符串并剖析出index.html就好办啦,easy,开始吧//由于现在只需要第一行,所以咱们就不像上面那样循环读取了,读一行就够了 String line = reader.readLine(); //用字符串截取函数,把“index.html”这个字符串给揪出来String url = line.substring(5, line.indexOf("HTTP") - 1); 3、所以咱们index.html的绝对路径就是 base_url + url 了,终于把我爱的人从人山人海中找到了,看看她怎么回复我吧——获取文件内容inputStream = new FileInputStream(base_url + url); OutputStream outputStream = socket.getOutputStream(); //我要从服务器给客户端回复了,对于服务器来说,这是发出去的内容,所以是Out! byte[] buffer = new byte[4 * 1024]; //界说字节缓冲区 int len = 0; while ((len = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, len); //很重要!通过socket的outputStream把咱们剖析出来的文件内容一字不落的发出去 如果没写这个,导致你爱的跟你表明的抑郁而死,活该你只身 } outputStream.flush(); //如果最后一次write时没有把buffer写满,是不会自动发出去的,需要挪用flush方法强制把内容从缓冲区发出去 好了,文件读取出来了,也返回给客户端了,亲爱哒他能收到吗?还是一样,务必先运行服务器端法式,然后打开浏览器输入127.0.0.1/index.html 后回车。我紧张,我激动,能不能收到回复,会给我什么样的回复?如图。为什么会这样???!!! 好吧,看看女神的index.html文件里都写了些什么。

Welcome

王欢,你是个好人...

看到这里,我到底应该兴奋还是欲绝。兴奋的是,我女神给我回复了;欲绝的是。那么问题来了,,,学表明技术哪家强?玩笑归玩笑,那我们的针对这次的浅谈题目是不是就完成了?可以说是的,可是我表明一次失败就算了?我还要表明第二次!(其实我倒不是这样的,这里只能牺牲我的人品来为了大家更好的明白了,呵呵)。

好吧,我适才的事情目录下另有个another.html,这次我来跟她表明吧!好!继续在浏览器中输入127.0.0.1/another.html后回车,期待这次会表明乐成。可是我等啊等,浏览器在那里打圈圈,岂非浏览器都知道我太花心了,拒绝帮我通报情书?好吧,我再打开浏览器试一下,输入127.0.0.1/index.html ,嗯?连第一个女神都不理我了?!我靠!为毛!激动是妖怪!岑寂!我打开eclipse控制台,发现服务器基础就没有“正在等候情书中…”,所以我托付浏览器发已往的情书固然就发丢了,因为基础没人在吸收啊。

(窃喜,还好不是因为我太花心了所以浏览器没有帮我投递情书)可是为什么呢?岑寂吧,分析代码。其实我们可以想到,这段代码执行完一次后不就竣事了吗,那我第二次给她发请求她固然会收不到了。对啊,那为相识决这个问题,怎么办呢?跪求红娘支招!红娘说:“给服务器法式个死循环吧,让她重复在等客户端的请求就好了。

”(其实红娘就一直在死循环中)红娘果真是红娘(否则是谁。),那就根据她的说法试一试呗!改代码,加入 while (true) 死循环:public class MultiWebServer { public static void main(String[] args) { String base_url = "E://课件/盘算机网络原理/实验/实验1/"; while (true) { try { ServerSocket serverSocket = new ServerSocket(80); System.out.println("正在等候情书中..."); Socket socket = serverSocket.accept(); System.out.println("收到情书,我要开始剖析!"); InputStream inputStream = socket.getInputStream(); BufferedReader reader = new BufferedReader( new InputStreamReader(inputStream)); String line = reader.readLine(); System.out.println(line); String url = line.substring(5, line.indexOf("HTTP") - 1); System.out.println("情书剖析完毕,我要想想怎么回复了..."); // 获取文件内容 inputStream = new FileInputStream(base_url + url); OutputStream outputStream = socket.getOutputStream(); byte[] buffer = new byte[4 * 1024]; int len = 0; while ((len = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, len); } outputStream.flush(); System.out.println("情书请求已发送给客户端"); //关闭对应的资源 serverSocket.close(); socket.shutdownInput(); socket.close(); inputStream.close(); reader.close(); outputStream.close(); } catch (Exception e) { } } } }这样,这位红娘就在这里一直等啊等,来了一个客户端我就处置惩罚他的情书请求,处置惩罚完这个继续循环以相同的方式等,处置惩罚,等,处置惩罚。

好吧,咱们接下来试一下,还是务必先运行服务器端法式,然后先和第一个女神表明,即 127.0.0.1/index.html 还是好朋侪的话,就别问我返回效果。这个时候打开eclipse的控制台,有没有发现右上角的红色暂停标志可以点击,那就说明咱们的红娘还在兢兢业业的事情着!好了,抓紧时间赶快向第二个女神表明,看她怎么说, 浏览器输入 127.0.0.1/another.html ,回车!好快啊,女神给我回复了。这。(她怎么知道不到十分钟?你是不是突然想到了cookie可以记载客户端的信息,不外咱们这里没用到cookie)还是看看another.html文件里写了什么吧 Welcome

我记得你刚和别人表明吧,还不外十分钟,你怎么会是个好人!

好吧,我啥也不说了,亲们,我还要向第三个女神表明吗。

?浏览器主动跟我说:“你表明吧,这次你发几多封表明信我都能给你送到服务器那里,因为她一直在等候着我给她发送呢!”想想,还是算了,人生如此,何须多言。代码都贴出来了,其实看起来挺简朴的,可是实际操作中会遇到种种各样的问题。另有一些要再继续唠叨的边角料:1、Q:什么是端口?A:这是一个比力抽象的观点,是为了历程间通信,每一个历程只能占用一个端口,也就是说多个历程绝不能同时占用一个端口2、Q:既然多个历程不能同时占用一个端口,那么咱们常说的web服务默认使用的是80端口,我电脑有三个浏览器,谷歌,360,IE他们却可以同时上网,这不是端口冲突了吗?A:常说的web服务使用80端口指的是服务器监听web请求的端口,是服务器,不是你自己的客户机。一般来说,一个应用法式打开后会见网络当地操作系统为其分配的端口号是随机的,所以三个浏览器虽然同时吸收web服务器的回复报文,由于他们三个各自占用的端口纷歧样,所以不会发生冲突。

3、Q:既然我的应用法式使用的端口都是随机的,服务器吸收到请求后怎么知道它要把应答报文发给谁?A:靠Socket!通过适才的编程实战,在我明白,Socket肯定会至少包罗四部门内容:IP地址,端口号,输入流和输出流。也就是说,从客户机发给服务器的Socket里一定会有客户机的IP地址和相应应用法式的端口号,这样服务器自然就知道应该把应答报文发给谁了。

4、Q:非要使用80端口吗?A:纷歧定。我们适才在编程的时候确实使用的是80端口,所以我们在浏览器中输入127.0.0.1/index.html,浏览器会默认认为我们会向127.0.0.1主机的80号端口发送请求。可是,这个80端口号只是默认的而已,我们完全可以自己改掉,好比在java代码里把服务器端的ServerSocket改成 ServerSocket serverSocket = new ServerSocket(3456); 这时候我们在浏览器中就要输入 127.0.0.1:3456/index.html 了,效果是一样的,可以浅尝辄止一下。5、Q:谁是客户端,谁是服务器?A:咱们只有一台电脑,这台电脑既充当着客户端的角色,又充当着服务器的角色。

当浏览器请求网页时,它是客户端;当80端口收到请求报文并应答时,它就是服务器。实在不明白,就想想什么是自恋吧,或者,自交也委曲可以。

6、Q:另有什么问题,接待留言~对于此用java编写的web服务器的一点简朴说明:此段代码很是简朴,所以肯定不会是真正web服务器所用到的代码,咱们这个只是能够应答最最基本的web请求,不能检测是否跨域会见等等。不外最基本的,用的socket编程是肯定的。另外,对于此段法式,只给出了处置惩罚输入输出流的一种方式。对于输入流,除了咱们适才用到的BufferedReader包装类,还可以直接用InputStream的read()方法等;对于输出流,除了咱们适才用的OutputStream的write()方法,还可用BufferedWritter,PrintWritter等,这些都是java IO的基本用法,凭据网络情况,凭据所要读取的文件巨细来时时变通,这就是仁者见仁智者见智了。

文章写到了最后,不知道该怎么收尾了,安平静静做个法式员吧,挺好。


本文关键词:新京葡萄官网入口,新京葡萄官方网站

本文来源:新京葡萄官网入口-www.nicoledominique.com

旋转小火锅定制流程

免费咨询

提供图纸

免费设计

免费报价

无忧安装

终身维护