少年阿宾

那些青春的岁月

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks

       Web服务器与客户端的通信使用HTTP协议(超文本传输协议),所以也叫做HTTP服务器。用Java构造Web服务器主要用二个类,java.net.Socket和java.net.ServerSocket,来实现HTTP通信。因此,本文首先要讨论的是HTTP协议和这两个类,在此基础上实现一个简单但完整的Web服务器。
  一、超文本传输协议
  Web服务器和浏览器通过HTTP协议在Internet上发送和接收消息。HTTP协议是一种请求-应答式的协议——客户端发送一个请求,服务器返回该请求的应答。HTTP协议使用可靠的TCP连接,默认端口是80。HTTP的第一个版本是HTTP/0.9,后来发展到了HTTP/1.0,现在最新的版本是HTTP/1.1。HTTP/1.1由
 RFC 2616 定义(pdf格式)。
  本文只简要介绍HTTP 1.1的相关知识,但应该足以让你理解Web服务器和浏览器发送的消息。如果你要了解更多的细节,请参考RFC 2616。
  在HTTP中,客户端/服务器之间的会话总是由客户端通过建立连接和发送HTTP请求的方式初始化,服务器不会主动联系客户端或要求与客户端建立连接。浏览器和服务器都可以随时中断连接,例如,在浏览网页时你可以随时点击“停止”按钮中断当前的文件下载过程,关闭与Web服务器的HTTP连接。
  1.1 HTTP请求
  HTTP请求由三个部分构成,分别是:方法-URI-协议/版本,请求头,请求正文。下面是一个HTTP请求的例子:
GET /servlet/default.jsp HTTP/1.1
Accept: text/plain; text/html
Accept-Language: en-gb
Connection: Keep-Alive
Host: localhost
Referer: http://localhost/ch8/SendDetails.htm
User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)
Content-Length: 33
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
userName=JavaJava&userID=javaID

 请求的第一行是“方法-URI-协议/版本”,其中GET就是请求方法,/servlet/default.jsp表示URI,HTTP/1.1是协议和协议的版本。根据HTTP标准,HTTP请求可以使用多种请求方法。例如,HTTP 1.1支持七种请求方法:GET,POST,HEAD,OPTIONS,PUT,DELETE,和TRACE。在Internet应用中,最常用的请求方法是GET和POST。
  URI完整地指定了要访问的网络资源,通常认为它相对于服务器的根目录而言,因此总是以“/”开头。URL实际上是
URI 一种类型。最后,协议版本声明了通信过程中使用的HTTP协议的版本。
  请求头包含许多有关客户端环境和请求正文的有用信息。例如,请求头可以声明浏览器所用的语言,请求正文的长度,等等,它们之间用一个回车换行符号(CRLF)分隔。
  请求头和请求正文之间是一个空行(只有CRLF符号的行),这个行非常重要,它表示请求头已经结束,接下来的是请求的正文。一些介绍Internet编程的书籍把这个CRLF视为HTTP请求的第四个组成部分。
  在前面的HTTP请求中,请求的正文只有一行内容。当然,在实际应用中,HTTP请求正文可以包含更多的内容。
  1.2 HTTP应答
  和HTTP请求相似,HTTP应答也由三个部分构成,分别是:协议-状态代码-描述,应答头,应答正文。下面是一个HTTP应答的例子:
HTTP/1.1 200 OK
Date: Tue, 06 Mar 2012 12:32:58 GMT
Server: Apache/2.2.22 (Win32)
Last-Modified: Tue, 06 Mar 2012 11:46:06 GMT
ETag: “b000000008d9e-57-4ba9196947acd”
Accept-Ranges: bytes
Content-Length: 87
Content-Type: text/html

经过测试,可以使用滴
//实例一:
package com.abin.lii.han.socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URLEncoder;

public class SocketGetServletTest {
 public static void main(String[] args) {
   BufferedWriter httpGetWriter = null;
         BufferedReader httpResponse = null;
         try {
             String hostname = "localhost";// 主机,可以是域名,也可以是ip地址
             int port = 1443;// 端口
             InetAddress addr = InetAddress.getByName(hostname);
             // 建立连接
             Socket socket = new Socket(addr, port);
             // 创建数据提交数据流
             httpGetWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "GBK"));
             // 相对主机的请求地址
             StringBuffer httpSubmitPath = new StringBuffer("/abin/ImediaRegister?");
//             StringBuffer httpSubmitPath = new StringBuffer("http://localhost:7200/abin/ImediaRegister?");
             httpSubmitPath.append(URLEncoder.encode("app", "GBK"));
             httpSubmitPath.append("=");
             httpSubmitPath.append(URLEncoder.encode("longcodeimedia", "GBK"));
             httpSubmitPath.append("&");
             httpSubmitPath.append(URLEncoder.encode("udid", "GBK"));
             httpSubmitPath.append("=");
             httpSubmitPath.append(URLEncoder.encode("123456789", "GBK"));
             httpSubmitPath.append("&");
             httpSubmitPath.append(URLEncoder.encode("source", "GBK"));
             httpSubmitPath.append("=");
             httpSubmitPath.append(URLEncoder.encode("limei", "GBK"));
             httpSubmitPath.append("&");
             httpSubmitPath.append(URLEncoder.encode("returnFormat", "GBK"));
             httpSubmitPath.append("=");
             httpSubmitPath.append(URLEncoder.encode("2", "GBK"));
             httpGetWriter.write("GET " + httpSubmitPath.toString() + " HTTP/1.1\r\n");
             httpGetWriter.write("Host: localhost:7200\r\n");
             httpGetWriter.write("UserAgent: IE8.0\r\n");
             httpGetWriter.write("Connection: Keep-Alive\r\n");
             httpGetWriter.write("\r\n");
             httpGetWriter.flush();
             // 创建web服务器响应的数据流
             httpResponse = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));
             // 读取每一行的数据.注意大部分端口操作都需要交互数据。
             String lineStr = "";
             while ((lineStr = httpResponse.readLine()) != null) {
                 System.out.println(lineStr);
             }
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
             try {
                 if (httpGetWriter != null) {
                     httpGetWriter.close();
                 }
                 if (httpResponse != null) {
                     httpResponse.close();
                 }
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
     }

       
}



//实例二

package com.abin.lii.han.socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;

public class SocketGetServletTest1 {

 public static void main(String[] args) {
  try {
   Socket socket = new Socket(InetAddress.getLocalHost(), 7200);
   BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
   StringBuffer buffer = new StringBuffer();
   buffer.append("GET http://localhost:7200/abin/ImediaRegister?app=2 HTTP/1.1\r\n");
   buffer.append("Host: localhost:7200\r\n");
   buffer.append("UserAgent: IE8.0\r\n");
   buffer.append("Connection: Keep-Alive\r\n");
   // 注,这是关键的关键,忘了这里让我搞了半个小时。这里一定要一个回车换行,表示消息头完,不然服务器会等待
   buffer.append("\r\n");
   writer.write(buffer.toString());
   writer.flush();

   // --输出服务器传回的消息的头信息
   BufferedReader reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
   String line = null;
   StringBuilder builder=new StringBuilder();
   while((line=reader.readLine())!=null){
    builder.append(line);
   }
   String result=builder.toString();
   System.out.println("result="+result);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

}

 

posted on 2012-12-31 08:31 abin 阅读(3211) 评论(0)  编辑  收藏 所属分类: Socket

只有注册用户登录后才能发表评论。


网站导航: