`
wen866595
  • 浏览: 269026 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Java Socket Http

阅读更多

用Java  Socket 实现发送HTTP请求和读取响应。

 

public class LearnHttp {
	private static final byte CR = '\r';
	private static final byte LF = '\n';
	private static final byte[] CRLF = {CR, LF};

	public static void main(String[] args) throws UnknownHostException, IOException {
		new LearnHttp().testHttp();
	}
	
	public void testHttp() throws UnknownHostException, IOException {
		String host = "www.baidu.com";
		Socket socket = new Socket(host, 80);
		
		OutputStream out = socket.getOutputStream();
		InputStream in = socket.getInputStream();
		
		// 在同一个TCP连接里发送多个HTTP请求
		for(int i = 0; i < 2; i++) {
			writeRequest(out, host);
			readResponse(in);
			System.out.println("\n\n\n");
		}
	}
	
	private void writeRequest(OutputStream out, String host) throws IOException {
		// 请求行
		out.write("GET /index.html HTTP/1.1".getBytes());
		out.write(CRLF);		// 请求头的每一行都是以CRLF结尾的
		
		// 请求头
		out.write(("Host: " + host).getBytes()); // 此请求头必须
		out.write(CRLF);

		out.write(CRLF);		// 单独的一行CRLF表示请求头的结束

		// 可选的请求体。GET方法没有请求体
		
		out.flush();
	}

	private void readResponse(InputStream in) throws IOException {
		// 读取状态行
		String statusLine = readStatusLine(in);
		System.out.println("statusLine :" + statusLine);
		
		// 消息报头
		Map<String, String> headers = readHeaders(in);
		
		int contentLength = Integer.valueOf(headers.get("Content-Length"));
		
		// 可选的响应正文
		byte[] body = readResponseBody(in, contentLength);
		
		String charset = headers.get("Content-Type");
		if(charset.matches(".+;charset=.+")) {
			charset = charset.split(";")[1].split("=")[1];
		} else {
			charset = "ISO-8859-1";		// 默认编码
		}
		
		System.out.println("content:\n" + new String(body, charset));
	}
	
	private byte[] readResponseBody(InputStream in, int contentLength) throws IOException {
		
		ByteArrayOutputStream buff = new ByteArrayOutputStream(contentLength);
		
		int b;
		int count = 0;
		while(count++ < contentLength) {
			b = in.read();
			buff.write(b);
		}
		
		return buff.toByteArray();
	}
	
	private Map<String, String> readHeaders(InputStream in) throws IOException {
		Map<String, String> headers = new HashMap<String, String>();
		
		String line;
		
		while(!("".equals(line = readLine(in)))) {
			String[] nv = line.split(": ");		// 头部字段的名值都是以(冒号+空格)分隔的
			headers.put(nv[0], nv[1]);
		}
		
		return headers;
	}
	
	private String readStatusLine(InputStream in) throws IOException {
		return readLine(in);
	}
	
	/**
	 * 读取以CRLF分隔的一行,返回结果不包含CRLF
	 */
	private String readLine(InputStream in) throws IOException {
		int b;
		
		ByteArrayOutputStream buff = new ByteArrayOutputStream();
		while((b = in.read()) != CR) {
			buff.write(b);
		}
		
		in.read();		// 读取 LF
		
		String line = buff.toString();
		
		return line;
	}
	
}

 

值得记下的教训:

InputStream.read()返回-1表示流的结束,即流被关闭了。在这次实现同一个Socket发送多个HTTP请求的过程中,一开始总是以为一个响应报文的结束是在InputStream.read返回-1时,导致第一次读取响应时总是很久才结束,第二次的请求虽然发出去了,但响应总是空的。

读取第一次请求的响应要很久是因为,这是在等待服务器关闭连接,百度的基本上是60秒。第二次是空的是因为,请求虽然发出去了,但服务器写响应的流已经被关闭,所以也读不到响应。

 

导致这个问题的根本原因在于没有记住:TCP是面向流的,并不知道传输的消息的开始和结束,这是由上层的协议去控制的,这里是HTTP协议。

 

 

欢迎关注我的微信公众号: coderbee笔记

 

0
2
分享到:
评论

相关推荐

    java socket for http socket

    javac Server.java java.exe Server 查看说明 可以简单得到http请求头 便于分析http

    HTTP-and-Socket.rar_http socket_java socket http_socket_socket

    **Java中的HTTP和Socket** 1. **Java HTTP客户端**:Java内置的HttpURLConnection或第三方库如Apache HttpClient可以用来发送HTTP请求和处理响应。 2. **Java Socket编程**:使用java.net.Socket和ServerSocket类,...

    JAVA Socket编程实现文件上传

    Java Socket编程是网络编程的基础,它提供了在两个应用程序之间建立通信连接的能力。在这个场景中,我们讨论的是如何使用Java的Socket来实现文件上传功能,即从客户端将文件发送到服务器,然后保存到服务器的数据库...

    java之socket编程简单实例

    标签中的"java socket http"表明这个例子可能涉及HTTP协议。HTTP协议是基于TCP/IP的应用层协议,而Socket编程是TCP/IP通信的基础。在实际的HTTP服务中,服务器会解析HTTP请求,然后返回适当的HTTP响应。在我们的简单...

    java socket 用户真实IP测试

    总的来说,Java Socket在处理Nginx TCP转发时获取用户真实IP的关键在于正确解析和处理HTTP请求头中的"X-Forwarded-For"字段。同时,对网络架构和安全性的理解也是至关重要的。通过深入研究相关代码和实验,可以增强...

    java 用socket 下载http 网页

    java 用socket 下载http 网页, 供参考, 其精髓是socket和http头部报文

    java socket 学习资料

    - 在Java Socket中实现HTTP服务器,需要解析HTTP请求(GET、POST等),并返回适当的HTTP响应。 - GET请求通常用于获取资源,POST请求用于向服务器提交数据。 - 文件上传涉及到处理multipart/form-data格式的POST...

    Java Socket 实用教程

    8. **Java的网络功能与编程**:基础知识—Java的网络功能与编程(1).chm这部分可能介绍了Java的网络编程基础,如URL、URLConnection等,以及如何使用它们进行HTTP请求。 学习Java Socket编程不仅需要理解TCP/IP协议...

    Java socket的一个封装

    1. 满足具有Socket客户端需求的基本应用. 2. 满足具有Socket服务端的基本应用. 具备并发能力, 能满足可设定个数客户端连接. ...参考个人博客: http://blog.csdn.net/ostrichmyself/article/details/6618349

    一个简单的java socket程序

    学习这个简单的Java Socket程序,可以让你了解网络通信的基本原理,为进一步的网络编程,如HTTP、FTP等协议的实现打下基础。同时,也可以帮助你掌握Java的IO流操作,这对于处理任何类型的数据传输都是非常重要的。

    Java Socket实现的HTTP下载客户端

    1. 纯Java实现的HTTP下载客户端,不借助任何第三方库 2. 可以任意类型文件下载 3. 基于JAVA Socket编程 4. 演示了SwingUI如何通过Model更新View 5. 下载以后双击Jar就可以运行

    Java Socket PC端传输文件简易服务器客户端

    Java Socket编程是网络编程中的重要组成部分,主要用于在两台计算机之间建立双向通信通道,实现数据的交换。在Java中,Socket类和ServerSocket类是进行网络通信的核心工具,它们提供了客户端与服务器之间的连接和...

    java socket

    Java Socket是Java编程语言中用于网络通信的核心API,它提供了低级别的、面向连接的、基于TCP/IP的通信机制。在Java中,Socket是基于TCP(传输控制协议)的,为应用程序提供了一种可靠的、双向的通信方式。通过...

    Java实现Socket长连接和短连接

    在Java编程中,Socket是网络通信的基础,它允许两个应用程序通过TCP/IP协议进行数据传输。Socket连接分为两种类型:长连接和短连接。这两种连接方式各有特点,适用于不同的应用场景。 **1. 短连接(Short ...

    java socket 聊天室

    虽然Java Socket是基于TCP/IP协议的,但实际的聊天室应用可能还涉及到其他协议,如HTTP、FTP等,具体取决于项目的复杂性和需求。 以上就是基于Java Socket实现的聊天室所涉及的主要技术点,这个项目对于学习网络...

    socket 实现http下载

    本话题主要探讨如何使用Socket实现HTTP下载,这对于理解HTTP协议的工作原理和深入学习网络编程至关重要。 HTTP(超文本传输协议)是互联网上应用最广泛的一种网络协议,它定义了客户端和服务器之间的数据交互格式。...

    Java Socket实现简单的web服务器

    Java Socket实现简单的Web服务器是一个基础但实用的编程实践,它涉及到网络编程、HTTP协议和文件I/O等核心概念。在本项目中,我们利用Java的Socket API构建了一个基本的服务器,该服务器仅处理HTTP GET请求并返回...

    用java写socket.io客户端所需jar包

    - 连接到服务器:`Socket socket = IO.socket("http://your-server-url:port");` - 注册事件监听器:例如,`socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {...});` 用于监听连接成功事件。 - 发送和...

    Java Socket源码

    - Java Socket遵循TCP/IP协议栈,包括IP、TCP、应用层协议(如HTTP、FTP等)。理解这些协议有助于理解Socket的工作机制。 - 协议文档提供了Socket通信的具体规则,如报文格式、连接建立和关闭的流程等。 7. **...

    JAVA使用Socket编写HTTP服务器

    在Java编程语言中,使用Socket实现一个简单的HTTP服务器是一项基础但重要的技能。HTTP服务器是互联网上用于接收HTTP请求并返回响应的程序。本教程将详细解释如何通过Socket类来构建这样的服务器,同时会涉及到相关的...

Global site tag (gtag.js) - Google Analytics