Java 自定义客户端与服务器

一:浏览器如何请求数据基本原理

基本原理:

  当浏览器输入地址向服务器请求数据时,实际上浏览器会在内部建立一个Socket对象,把http请求报文转变成byet[]字节,然后调用Socket的方法把这些数据发送到服务器的,例如请求www/baidu.com的域名来会解析成对应的IP地址,解析成:http://202.108.22.5 :80/login.aspx 浏览器在解析到IP地址后,做的第二步就是对指定的URL进行HTTP封装,把URL封装成http报文,浏览器把URL封装成HTTP报文后,第三步做的事情就是将这个HTTP请求报文发送到服务器

浏览器在解析IP地址时流程:

  在网络上访问网站,要首先通过DNS服务器把网络域名(www.XXXX.com)解析成61.XXX.XXX.XXX的IP地址后,我们的计算机才能访问。要是对于每个域名请求我们都要等待域名服务器解析后返回IP信息,这样访问网络的效率就会降低,而Hosts文件就能提高解析效率。根据Windows系统规定,在进行DNS请求以前,Windows系统会先检查自己的Hosts文件中是否有这个地址映射关系,如果有则调用这个 IP地址映射,如果没有再向已知的DNS服务器提出域名解析。也就是说Hosts的请求级别比DNS高。

如何修改Host文件:

  找到电脑中C:\WINDOWS\system32\drivers\etc\hosts文件,在文件末尾加入如下图所示的ip与域名:

然后在浏览器中输入www.taobao.com就出现了如下图的效果,至于作用,你懂得!!!
==》

二:在浏览器访问本地(Tomcat)服务器

1:打开tomcat =》点击在tomcat主目录下的apache-tomcat-7.0.50\bin中的startup.bat 

2:在浏览器输入本地的浏览地址http://localhost:8888/myweb/    ==》我这里修改了端口为8888  一般是8080 就可以看到效果了

三:在浏览器中访问自定义的服务器

服务器代码:==》注意最后一定要关闭Socket..

 
package Demo1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Demo1
{

    public static void main(String[] args) throws IOException
    {
        ServerSocket ss = new ServerSocket(12346);
        //获取客户端对象
        Socket s = ss.accept();

//        BufferedReader br = new BufferedReader(new InputStreamReader(
//                s.getInputStream()));
//
//        String line = null;
//
//        while ((line = br.readLine()) != null)
//        {
//            System.out.println(line);//这里不能用这样的方法,会导致服务器回发不了数据集,浏览器并没有Socket结束标记
//        }
        //读取浏览器发送的数据
        InputStream in = s.getInputStream();
        byte[] b = new byte[1024];
        int len =in.read(b);
        System.out.println(new String(b,0,len));
        //给浏览器发送数据
        PrintWriter pw = new PrintWriter(s.getOutputStream(),true);

        pw.println("欢迎光临李鹏的服务器");

        pw.close();
        // 给浏览器发送数据
    /*    OutputStream out = s.getOutputStream();
        out.write("欢迎访问".getBytes());
        out.flush();*/
        in.close();
        s.close();
        ss.close();

    }

}
服务器代码

 在浏览器输入:http://localhost:12345/

就可以看到我们的服务器端给客户端发送了数据,如图:

而服务器端也接受到了浏览器传过来的数据,如图:

这样我们就可以理解他们的工作原理了...

四:在eclipse下访问Tomcat服务器

如果不知道如何写和他一样的http://localhost:8888/myweb/mail.html 的头信息文件时,可以利用上面第三种的方式在浏览器输入:http://localhost:12345/myweb/mail.html ,可以看到浏览器中提交信息

GET /myweb/mail.html HTTP/1.1
Host: localhost:12345 ==》将这里的12345修改为8888
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8 ==》别忘了加两行空格,否则有错

然后在自己定义的浏览器中,给服务器写入数据,再读取服务器的数据 

客户端代码:

 
package Demo1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class Demo1
{

    public static void main(String[] args) throws UnknownHostException, IOException
    {
        Socket s = new Socket(InetAddress.getByName("10.2.156.26"),8888);
        
        PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
        
        pw.println("GET /myweb/mail.html HTTP/1.1");
        pw.println("Host: localhost:8888");
        pw.println("Connection: keep-alive");
        pw.println("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
        pw.println("User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36");
        pw.println("Accept-Encoding: gzip,deflate,sdch");
        pw.println("Accept-Language: zh-CN,zh;q=0.8");
        pw.println("");
        pw.println("");

        
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        
        String line = null;
        while((line = br.readLine())!=null)
        {
            System.out.println(line);
        }
        br.close();
        pw.close();
        s.close();
        
    }

}
客户端代码

 结果:

 

其中:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Accept-Ranges: bytes
ETag: W/"995-1369649706000"
Last-Modified: Mon, 27 May 2013 10:15:06 GMT
Content-Type: text/html
Content-Length: 995
Date: Mon, 10 Aug 2015 12:34:35 GMT

这些是响应的头信息,在浏览器看不到的,而其他代码就由浏览器接收到然后解析成为了一个页面

五:高级的访问服务器的方法

通过封装为URL对象来访问网页

 java代码:

package Demo1;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;



public class Demo1
{

    public static void main(String[] args) throws IOException
    {
        String path = "http://10.2.156.26:8888/myweb/mail.html?name=aa";
        
        URL url = new URL(path);
        
        /*System.out.println(url.getProtocol());//http
        System.out.println(url.getHost());        //10.2.156.26
        System.out.println(url.getPort());        //8888
        System.out.println(url.getPath());//  /myweb/mail.html
        System.out.println(url.getFile());//  /myweb/mail.html?name=aa
         */        
        URLConnection conn = url.openConnection();
        //读取服务器端返回的数据
        InputStream in = conn.getInputStream();
        byte[] arr = new byte[1024];
        int len = in.read(arr);
        System.out.println(new String(arr,0,len));
        
    }

}
代码

结果:

 

可以看到这里是没有响应的头信息的..

六:综合应用==》爬虫(获取到网页中所有的邮箱)

代码:

public class Demo1
{

    /**
     * 实现网页爬虫
     */
    public static void main(String[] args) throws IOException
    {

        // getEmails();
        getEmail();
    }

    // 从网络上的网页获取邮箱
    public static void getEmail() throws IOException
    {
        String path = "http://localhost:8888/myweb/mail.html";

        URL url = new URL(path);

        URLConnection conn = url.openConnection();

        InputStream in = conn.getInputStream();// 读取服务器端返回的mail.html文件的数据
        BufferedReader br = new BufferedReader(new InputStreamReader(in,
                "utf-8"));

        String regex = "\\w+@\\w+(\\.\\w+)+";
        Pattern p = Pattern.compile(regex);

        String line = null;
        while ((line = br.readLine()) != null)
        {

            // 使用Matcher对象从读取的一行中获取符合邮箱规则的内容
            //System.out.println(line);
            Matcher m = p.matcher(line);
            while (m.find())
            {
                System.out.println(m.group());
            }
        }

    }

    // 从本地文件中获取所有的邮箱
    public static void getEmails() throws IOException
    {
        // 创建读取本地文件的读取流
        BufferedReader br = new BufferedReader(
                new FileReader("file\\mail.html"));

        String regex = "\\w+@\\w+(\\.\\w+)+";
        Pattern p = Pattern.compile(regex);

        String line = null;
        while ((line = br.readLine()) != null)
        {
            // 使用Matcher对象从读取的一行中获取符合邮箱规则的内容
            Matcher m = p.matcher(line);
            while (m.find())
            {
                System.out.println(m.group());
            }
        }
        br.close();
    }

}
爬虫代码

 

 结果:
 

 

posted @ 2015-08-10 20:41  李_鹏  阅读(865)  评论(0编辑  收藏  举报