部分参考自: http://www.blogjava.net/landon/archive/2013/07/02/401137.html
相对程序而言,write从内存发送出去,read是读入内存了,可以模拟管道来想,管道的一头是出水(write),管道一遍是进水(read)。
public class HTTPClient
{
String host = "www.javathinker.org";
int port = 80;
Socket socket;
public void createSocket() throws Exception
{
socket = new Socket(host,port);
}
//访问网页www.javathinker.org/index.jsp
public void communication() throws Exception
{
//组装http请求协议
StringBuffer sb = new StringBuffer("GET " + "/index.jsp" + " HTTP/1.1\r\n");
sb.append("Host:www.javathinker.org\r\n");
sb.append("Accept:*/*\r\n");
sb.append("Accept-Language:zh-cn\r\n");
sb.append("Accept-Encoding:gzip,deflate\r\n");
sb.append("User-Agent:Mozilla/4.0(compatible;MSIE 6.0;Window NT 5.0)\r\n");
sb.append("Connection:Keep-Alive\r\n\r\n");
//发出http请求->request
OutputStream socketOut = socket.getOutputStream();
// 发送数据时,先把字符串形式的请求信息转换为字节数组,即字符串的编码 sb.toString().getBytes()
socketOut.write(sb.toString().getBytes());//参考下面的红色部分,此处是将sb的内容写入到socketOut里面。
socket.shutdownOutput();//关闭输出流
//接收响应结果->response
InputStream socketIn = socket.getInputStream();
// 接收数据时把接收到的字节写到一个ByteArrayOutputSteam中,其是一个容量能够自动增长的缓冲区.
//socketIn.read(buff)返回-1,则表示独到了输入流的末尾
// 问题,如果接收的网页数据量很大,则先把这些数据全部保存在ByteArrayOutputSteam,很不明智,因为这些数据会占用大量内存.->
//更有效的做法是利用BufferReader来逐行读取数据
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int len = -1;
while((len = socketIn.read(buff)) != -1)//read(); 将read前的东西读入到read的括号里。socketIn是输入流,输入流和read结合使用。
{
//将buff写入buffer
buffer.write(buff, 0, len);//write(); 将write括号里的内容写入到write前的东西里(此处write前的东西是buffer)。buffer是输出流,输出流和write结合 //使用。
}
System.out.println(new String(buffer.toByteArray()));//把字节数组转为字符串
socket.close();
}