Java SocketServer实现的http服务器,火狐不能识别响应报文,求大神帮助

Java SocketServer实现的http服务器,火狐不能识别响应报文,求大神帮助,第1张

boswrite("HTTP/11 200 OK\r\n"getBytes());//响应头开始

boswrite("Content-Type: image/jpg\r\n"getBytes());

boswrite(("Content-Length: "+length+"\r\n")getBytes());

boswrite(("Last-Modified: "+ new Date()toGMTString()+"\r\n")getBytes());

boswrite("\r\n"getBytes());//响应头结束响应正文开始

bos直接是socketgetOutputStream()。别的代码和你上面的一致。FF最新版测试正常显示jpg

测试的全文件

import javaio;

import javanet;

import javautilDate;

public class SocketHttp{

    public static void main(String args[])throws Exception{

        new SocketHttp()test();

    }

    public void test()throws Exception{

        ServerSocket ser=new ServerSocket(8080);

        new WriteThread(seraccept())start();

    }

    

    class WriteThread extends Thread{

        public WriteThread(Socket sk){

            thissk=sk;

        }

        Socket sk;

        public void run(){

            try{

                OutputStream bos = skgetOutputStream();//首先有个

                File img = new File("IMAG0693_resizejpg");

                InputStream is = new FileInputStream(img);

                long length = isavailable();//响应状态行

                boswrite("HTTP/11 200 OK\r\n"getBytes());//响应头开始

                boswrite("Content-Type: image/jpg\r\n"getBytes());

                boswrite(("Content-Length: "+length+"\r\n")getBytes());

                boswrite(("Last-Modified: "+ new Date()toGMTString()+"\r\n")getBytes());

                boswrite("\r\n"getBytes());//响应头结束响应正文开始

                bosflush();

                int len;

                byte[] buffer = new byte[1024];

                while ((len = isread(buffer)) > 0) {

                    boswrite(buffer, 0, len);

                }

                bosflush();

                boswrite("\r\n\r\n"getBytes());//响应正文结束

                bosclose();

            }catch(Exception ex){

                exprintStackTrace();

            }

        }

    }

}

咱的理解:

当应用程序读取完响应体内容后或者调用 close() 关闭了URLConnectiongetInputStream()返回的流,

JDK中的HTTP协议句柄将关闭连接,并将连接放到连接缓存中。下次获取URLConnection示例,并获取InputStream流时,会再次使用之前打开的TCP连接。

也就是说:

public static String sendPost(String url, String param) { String result = ""; try { URL httpurl = new URL(url); HttpURLConnection httpConn = (HttpURLConnection) httpurlopenConnection(); httpConnsetDoOutput(true); httpConnsetDoInput(true); PrintWriter out = new PrintWriter(httpConngetOutputStream()); outprint(param); outflush(); outclose(); BufferedReader in = new BufferedReader(new InputStreamReader(httpConngetInputStream())); String line; while ((line = inreadLine()) != null) { result += line; } inclose(); } catch (Exception e) { Systemoutprintln("没有结果!" + e); } return result; }

咱在间隔较短的时间内调用上面的方法(连接的地址不一样,但还是同一个服务器同一个项目),用的是同一个TCP连接。咱这么理解对吗?不对的话请具体讲讲。谢谢。

因为 Apache 现在只使用了 192168xx:80 ,而你可以使用另外的尚未使用的127001:80 没指定 IP 表示监听在所有可能的 IP 上,包括虚拟的 ipv6,loopback,vmware 虚拟的网卡。

问题简化一下:对一个ip,一个线程请求100次。该次请求的响应时间为调用httpClient前的响应时间减去接收到httpClient响应的时间。注意,本次请求是否有效要判断。平均响应时间和最大响应时间只不过是响应时间的统计而已,可以用数据库来做。

就是说数据库记录每次测试请求的响应时间,成功与否。统计数据最后出来。

只所以用多线程,是因为单线程顺序请求100次,不能模拟服务器真正的情况。

随着互联网的不断发展,用户在访问互联网的时候使用的终端设备类型也在不断的变化,但是这些都是基于http协议来实现的,下面我们就简单分析一下,http发送请求的处理过程。

HTTP协议是基于TCP协议的,所以它使用面向连接的方式发送请求,通过stream二进制流的方式传给对方。

当然,到了TCP层,它会把二进制流变成一个的报文段发送给服务器。

在发送给每个报文段的时候,都需要对方有一个回应ACK,来保证报文可靠地到达了对方。

如果没有回应,那么TCP这一层会进行重新传输,直到可以到达。

同一个包有可能被传了好多次,但是HTTP这一层不需要知道这一点,因为是TCP这一层在埋头苦干。

TCP层发送每一个报文的时候,都需要加上自己的地址(即源地址)和它想要去的地方(即目标地址),将这两个信息放到IP头里面,交给IP层进行传输。

IP层需要查看目标地址和自己是否是在同一个局域网。

如果是,就发送ARP协议来请求这个目标地址对应的MAC地址,然后将源MAC和目标MAC放入MAC头,发送出去即可。

如果不在同一个局域网,就需要发送到网关,还要需要发送ARP协议,来获取网关的MAC地址,然后将源MAC和网关MAC放入MAC头,发送出去。

网关收到包发现MAC符合,取出目标IP地址,根据路由协议找到下一跳的路由器,获取下一跳路由器的MAC地址,将包发给下一跳路由器。

这样路由器一跳一跳终于到达目标的局域网。

这个时候,后一跳的路由器能够发现,目标地址就在自己的某一个出口的局域网上。

于是,在这个局域网上发送ARP,获得这个目标地址的MAC地址,将包发出去。

目标的机器发现MAC地址符合,就将包收起来;发现IP地址符合,根据IP头中协议项,知道自己上一层是TCP协议,于是解析TCP的头,里面有序列号,IT培训http://wwwkmbdqncn/建议需要看一看这个序列包是不是我要的,如果是就放入缓存中然后返回一个ACK,如果不是就丢弃。

TCP头里面还有端口号,HTTP的服务器正在监听这个端口号。

于是,目标机器自然知道是HTTP服务器这个进程想要这个包,于是将包发给HTTP服务器。

HTTP服务器的进程看到,原来这个请求是要访问一个网页,于是就把这个网页发给客户端。

服务器端接收客户端的请求的话,需要在服务器端的java文件实现HttpServlet这个接口,并且在webxml里配置一个客户端的请求拦截。

webxml里的代码里添加

<servlet>

   <servlet-name>testServlet</servlet-name><!--这个名字可以自己定-->

   <servlet-class>comsuntestServlet</servlet-class><!--这里是你需要接收客户端请求的那个类以及包名,也就是下面拦截到的url会转发到的那个类-->

  </servlet>

  <servlet-mapping>

   <servlet-name>testServlet</servlet-name><!--和上面的name需要一样-->

   <url-pattern>/</url-pattern><!--什么类型的客户端请求会被拦截,/ 就是全拦截了-->

</servlet-mapping>

然后再服务器端的类文件,要实现 HttpServlet这个接口。并把doGet()方法和doPost()方法重写。

这两种方法分别对应的是客户端的get请求和post请求的处理,你的是post请求的话,就在doPost()方法内,写你的业务。

然后再用下面两句话,设置你要返回客户端的数据。

//这是设置你要返回去的数据。value才是你的数据,key是标签。

requestsetAttribute("key", "value");  

//这是设置你要返回去testjsp这张页面。

requestgetRequestDispatcher("testjsp")forward(request, response);

不知道你是不是这个意思,你可以再去看看相关servlet方面的知识,

关于客户端和服务器端大概也就是有个servlet作为请求的拦截

然后经过相关判断后,选择性的传到服务器的相应类里面。

再经过类里面的业务,把得到需要的数据回传到指定的页面上。

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » Java SocketServer实现的http服务器,火狐不能识别响应报文,求大神帮助

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情