- 浏览: 1338224 次
- 性别:
- 来自: 湖南澧縣
文章分类
最新评论
-
虾米小尹:
不行啊!2.2-0.25=1.9500000000000002 ...
JavaScript浮点数运算 —— 精度问题 -
heluping000000:
引用String a= "abc",首先在 ...
String,到底创建了多少个对象? -
mack:
谢谢分享matcher.appendReplacement(s ...
string.replaceAll()中的特殊字符($ \)与matcher.appendReplacement -
wzt3309:
完全理解,比网上其他资料都要详细
String,到底创建了多少个对象? -
u014771876:
Java中十六进制转换 Integer.toHexString()
在上次Java Socket现实简单的HTTP服务我们实现了简单的HTTP服务,它可以用来模拟HTTP服务,用它可以截获HTTP请求的原始码流,让我们很清楚的了解到我们向服务发的HTTP消息的结构,对HTTP请求消息有个清晰的认识。这一节我想写了一个客户的程序,就是用来模拟浏览器,用来向服务器发送HTTP请求,最得要的是可以用它来显示服务器发回来的HTTP响应消息的一般结构。
下面是代码实现:
import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import java.util.ArrayList; /** * 一个简单的HTTP客户端,发送HTTP请求,模拟浏览器 * 可打印服务器发送过来的HTTP消息 */ public class SimpleHttpClient { private static String encoding = "GBK"; public static void main(String[] args) { try { Socket s = new Socket(InetAddress.getLocalHost(), 8080); OutputStreamWriter osw = new OutputStreamWriter(s.getOutputStream()); StringBuffer sb = new StringBuffer(); sb.append("GET /HttpStream/gb2312.jsp HTTP/1.1\r\n"); sb.append("Host: localhost:8088\r\n"); sb.append("Connection: Keep-Alive\r\n"); //注,这是关键的关键,忘了这里让我搞了半个小时。这里一定要一个回车换行,表示消息头完,不然服务器会等待 sb.append("\r\n"); osw.write(sb.toString()); osw.flush(); //--输出服务器传回的消息的头信息 InputStream is = s.getInputStream(); String line = null; int contentLength = 0;//服务器发送回来的消息长度 // 读取所有服务器发送过来的请求参数头部信息 do { line = readLine(is, 0); //如果有Content-Length消息头时取出 if (line.startsWith("Content-Length")) { contentLength = Integer.parseInt(line.split(":")[1].trim()); } //打印请求部信息 System.out.print(line); //如果遇到了一个单独的回车换行,则表示请求头结束 } while (!line.equals("\r\n")); //--输消息的体 System.out.print(readLine(is, contentLength)); //关闭流 is.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /* * 这里我们自己模拟读取一行,因为如果使用API中的BufferedReader时,它是读取到一个回车换行后 * 才返回,否则如果没有读取,则一直阻塞,直接服务器超时自动关闭为止,如果此时还使用BufferedReader * 来读时,因为读到最后一行时,最后一行后不会有回车换行符,所以就会等待。如果使用服务器发送回来的 * 消息头里的Content-Length来截取消息体,这样就不会阻塞 * * contentLe 参数 如果为0时,表示读头,读时我们还是一行一行的返回;如果不为0,表示读消息体, * 时我们根据消息体的长度来读完消息体后,客户端自动关闭流,这样不用先到服务器超时来关闭。 */ private static String readLine(InputStream is, int contentLe) throws IOException { ArrayList lineByteList = new ArrayList(); byte readByte; int total = 0; if (contentLe != 0) { do { readByte = (byte) is.read(); lineByteList.add(Byte.valueOf(readByte)); total++; } while (total < contentLe);//消息体读还未读完 } else { do { readByte = (byte) is.read(); lineByteList.add(Byte.valueOf(readByte)); } while (readByte != 10); } byte[] tmpByteArr = new byte[lineByteList.size()]; for (int i = 0; i < lineByteList.size(); i++) { tmpByteArr[i] = ((Byte) lineByteList.get(i)).byteValue(); } lineByteList.clear(); return new String(tmpByteArr, encoding); } }
运行时访问一个页面打印如下:
HTTP/1.1 200 OK |
下面来个文件下载的看怎么样?
请求的Jsp页面如下:
<%@page import="java.io.InputStream" contentType="text/html; charset=GB2312"%> <%@page import="java.io.FileInputStream"%> <%@page import="java.io.OutputStream"%><html> <body> <br> <% try { InputStream is = new FileInputStream("e:/tmp/file2.txt"); OutputStream os = response.getOutputStream(); byte[] readContent = new byte[1024]; int readCount = 0; while (is.available() > 0) { readCount = is.read(readContent); os.write(readContent, 0, readCount); } is.close(); //注这里一定要关闭,不然的话抛异常,异常请见下面,原因就是response.getWriter() //与response.getOutputStream()不能同时使用,如果在这里关闭了,前面与后面向 //out对象里写的数据就不会刷新到客户端了,只有向response.getOutputStream()写的 //数据会输出到客户端。 os.close(); } catch (Exception e) { e.printStackTrace(); } %> </body> </html>
如里上面Jsp下载页面中的 os.close() 注释掉的话会抛如下异常:
exception
org.apache.jasper.JasperException: getOutputStream() has already been called for this response org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:476) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:383) org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315) org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265) javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
root cause
java.lang.IllegalStateException: getOutputStream() has already been called for this response org.apache.catalina.connector.Response.getWriter(Response.java:601) org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:196) org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125) org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118) org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:185) org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:116) org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:76) org.apache.jsp.gb2312_jsp._jspService(gb2312_jsp.java:78) org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98) javax.servlet.http.HttpServlet.service(HttpServlet.java:803) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328) org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315) org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265) javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
以下是服务器经过编译生成的servlet类文件:
package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; import java.io.InputStream; import java.io.FileInputStream; import java.io.OutputStream; public final class gb2312_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent { private static java.util.List _jspx_dependants; public Object getDependants() { return _jspx_dependants; } public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException { JspFactory _jspxFactory = null; PageContext pageContext = null; HttpSession session = null; ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this; JspWriter _jspx_out = null; PageContext _jspx_page_context = null; try { _jspxFactory = JspFactory.getDefaultFactory(); response.setContentType("text/html; charset=GB2312"); pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; out.write("\r\n"); out.write("\r\n"); out.write("\r\n"); out.write("<html>\r\n"); out.write("\t<body> <br>\r\n"); out.write("\t\t"); try { InputStream is = new FileInputStream("e:/tmp/file2.txt"); OutputStream os = response.getOutputStream(); byte[] readContent = new byte[1024]; int readCount = 0; while (is.available() > 0) { readCount = is.read(readContent); os.write(readContent, 0, readCount); } is.close(); //注这里一定要关闭,不然的话抛异常,异常请见下面,原因就是response.getWriter() //与response.getOutputStream()不能同时使用,如果在这里关闭了,前面与后面向 //out对象里写的数据就不会刷新到客户端了,只有向response.getOutputStream()写的 //数据会输出到客户端。 os.close(); } catch (Exception e) { e.printStackTrace(); } out.write("\r\n"); out.write("\t</body>\r\n"); out.write("</html>"); } catch (Throwable t) { if (!(t instanceof SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0) out.clearBuffer(); if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); } } finally { if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context); } } }
最后是服务向客户端输出的码流如下:
HTTP/1.1 200 OK
这是测试文件的内容: |
发表评论
-
Java正则表达式
2014-03-14 10:16 1766Java正则表达式详解 作者:jzj 文 ... -
类的初始化与清理
2013-06-24 22:20 1457初始化时内存清零 当创建一个对象时,首先将在堆上为这个对象分 ... -
protected,这个错了吗?
2013-06-24 22:17 1251这几天对protected修饰符有点迷糊,随便找同事要了一本 ... -
Java中BigDecimal的8种舍入模式
2013-06-21 18:42 2186java.math.BigDecimal不可变的、任意精度的 ... -
Tomcat性能参数设置
2010-12-27 15:35 34805默认参数不适合生产环境使用,因此需要修改一些参数 1、 ... -
Java 6 JVM参数选项大全
2010-12-14 11:16 1638http://kenwublog.com/docs/java6 ... -
对象的安全构造
2013-06-21 18:43 1546在构造期间,不要公布“this”引用 一种可以将数据争用引 ... -
Java断言(assert)—— 转
2010-06-20 10:36 12103一、概述 在C和C++语言中都有assert关键,表示断言。 ... -
eclipse调试
2010-06-04 00:11 8084eclipse远程调试 在eclipse3.4前,远程调试时 ... -
protected,你真的理解了吗?
2010-05-09 17:56 2150Java中的访问控制修饰符有四个级别,但属protected最 ... -
利用反射进行深层克隆
2010-05-05 21:02 3672最近在看《effective java ... -
类与类之间的几种关系
2010-05-03 13:49 2419类和类、类和接口、接 ... -
运行java
2010-05-03 13:47 1054用javac命令编译一个打包的类时,如果没有加参数" ... -
Java内存模型与volatile
2010-04-25 13:21 18813内存模型描述的是程序 ... -
中断线程
2010-04-24 21:19 9000中断线程 线程的thread.i ... -
java中的关键字、保留字、标示符
2010-04-07 23:48 3378关键字 Java的关键字对java的编译器有特殊的意义, ... -
Java中的浮点数剖析
2010-04-07 23:27 4727定点数表达法的缺点在于其形式过于僵硬,固定的小数点位置决定了固 ... -
线程间的同步与互斥
2010-03-23 21:29 2305线程间的同步(实指线程间的通信):一般来说,一个线程相对于另 ... -
UTF-16、UTF-16BE、UTF-16LE编码方式的区别
2010-03-23 21:20 9829import java.io.IOException; ... -
final、finally、finalize
2010-01-22 01:15 2430final关键字 先看看final关键字,它可以被用于以下几个 ...
相关推荐
总的来说,Java的Socket类是实现网络通信的基础,通过创建Socket实例,我们可以与远程服务器建立连接,进行数据的发送和接收。了解和熟练掌握Socket类的使用,对于编写任何基于TCP协议的网络应用程序都是至关重要的...
这个简单的例子展示了Java Socket基本的发送和接收机制,但实际的网络应用可能会更复杂,包括多线程处理多个客户端、错误处理、数据编码和解码等。 总结来说,Java Socket编程是构建网络应用程序的关键技术,它允许...
本文将深入探讨如何利用Socket进行连续发送与连续接收数据,基于标题“利用socket连续发送与连续接收数据”以及描述中提到的实现过程。 首先,让我们理解什么是Socket。Socket是进程间通信的一种方式,它提供了一种...
Java Socket电子邮件发送与接收是基于Java网络编程技术实现的一种通信方式,主要涉及到Java的Socket类以及Email相关的API。本项目是一个课程项目,开发者通过几天的努力完成了一个具备图形用户界面(GUI)的邮件系统...
Java基于Socket的文件发送与接收是一个常见的网络编程任务,它涉及到客户端和服务器之间的通信,以及大数据量的传输。在本项目中,开发者为用户提供了一个图形用户界面(GUI),并且在传输过程中显示了进度条,这...
在这个场景中,我们讨论的是如何使用Java的Socket来实现文件上传功能,即从客户端将文件发送到服务器,然后保存到服务器的数据库中。这个过程涉及到多个关键知识点,下面我们将详细探讨。 1. **Java Socket基础**:...
Java基于socket实现的客户端和服务端通信功能完整实例 在Java中,Socket是实现网络通信的基础,通过Socket可以实现客户端和服务器端之间的通信。本文将详细介绍Java基于Socket实现的客户端和服务端通信功能,包括...
在Java编程语言中,Socket是实现网络通信的基础组件,它为两台计算机之间的通信提供了低级别的接口。在本文中,我们将深入探讨Java Socket客户端代码及其在创建基于Socket的聊天室客户端中的应用。 首先,理解...
本文将深入探讨如何在Android平台上利用Socket进行数据的发送与接收,以及服务器返回数据的处理。 首先,理解Socket的基本概念:Socket,又称为“套接字”,是网络编程中的一个接口,它提供了进程间通信(IPC,...
Java Socket 实现 SMTP 协议发送邮件 Java Socket 是 Java 语言中用于实现网络编程的 API,通过 Socket,可以实现与远程服务器的通信。在这里,我们将使用 Java Socket 实现 SMTP 协议来发送邮件。 SMTP 协议简介 ...
Java Socket多线程简易实现是网络编程中的一个基础概念,主要应用于客户端与服务器之间的通信。在Java中,Socket是基于TCP协议的,提供了一种可靠的、面向连接的字节流通信方式。多线程则是Java并发编程的重要特性,...
实现手机控制电脑端的部分,一般会涉及到移动设备的触摸事件转化为键盘鼠标事件模拟,这通常需要额外的协议设计和实现,例如将触摸事件转换为特定的控制指令,然后通过Socket发送到服务器,服务器再模拟这些操作。...
本篇将详细讲解如何在Java中实现基于Socket的自定义消息协议,以及客户端与服务器端的数据转换与解析过程。 首先,我们来看`SocketClient.java`,这是客户端的代码实现。客户端通常需要以下几个步骤: 1. 创建...
Java Socket 是一种网络通信协议,它是Java编程语言中实现客户端-服务器模型的基础。Socket 提供了低级别的、面向连接的、双向通信的网络接口,允许应用程序通过网络进行数据传输。在本示例中,我们将深入探讨Java ...
本教程将详细讲解如何利用Java Socket实现基于TCP/IP的服务端和客户端之间的报文发送与接收。 TCP(传输控制协议)是一种面向连接、可靠的传输协议,它确保了数据包的有序和无损传输。IP(互联网协议)则是互联网上...
Java Socket是Java编程语言中用于网络通信的核心API,它提供了低级别的、面向连接的、基于TCP/IP协议的网络通信能力。在"Java Socket 视频流转发Socket"这个主题中,我们将深入探讨如何使用Java Socket来处理视频流...
在IT行业中,网络通信是不可或缺...总的来说,利用Socket发送和接收邮件涉及到网络编程、邮件协议、Java的I/O和特定的Java邮件API。这不仅有助于开发自定义的邮件客户端,也有助于理解电子邮件在网络传输中的工作原理。
一旦连接建立,客户端也可以通过这个Socket发送和接收消息。 在GUI方面,我们可以使用Java的Swing或JavaFX库来创建聊天界面。用户可以通过文本框输入消息,点击发送按钮后,这些消息将通过Socket发送到服务器;同时...
在大文件传输中,Socket用于建立客户端与服务器之间的连接,并负责数据的发送和接收。 - **ServerSocket**:服务器端使用ServerSocket监听特定端口,等待客户端的连接请求。 4. **NIO(Non-blocking I/O)** - **...
Java Socket通信实现是Java网络编程中的重要组成部分,它允许两台计算机通过TCP/IP协议进行双向通信。在Java中,Socket提供了低级别的、基于连接的、面向数据流的通信API,可以用于实现客户端-服务器架构的应用程序...