java笔记30 网络编程2 服务器

来源:互联网 发布:mac模拟器windows 编辑:程序博客网 时间:2024/06/07 06:11

1.       客户端与服务器

    最常见的客户端:浏览器,IE/chrome。

最常见的服务端:服务器,Tomcat。

2.       服务器原理

看一下向服务器发送了什么请求。

import java.io.IOException;import java.io.*;import java.net.*; public class H_04ServerDemo{    public static void main(String[] args) throws Exception    {              ServerSocket ss=new ServerSocket(11000);        Socket s=ss.accept();         System.out.println(InetAddress.getLocalHost().getHostAddress());        InputStream in=s.getInputStream();        byte [] buf=new byte[1024];        int len=in.read(buf);        System.out.println(new String(buf,0,len));                  PrintWriter out=new PrintWriter(s.getOutputStream(),true);         out.println("<font color='red' size='7'> 大家好</font>");         s.close();         ss.close();    }}


运行后打开浏览器 http://192.168.0.100:11000/

                    显示红色7号字体的“大家好”

控制台打印以下信息:

192.168.0.100

GET / HTTP/1.1

Accept: image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/x-mfe-ipt, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*

Accept-Language: zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.6,en;q=0.4,ja;q=0.2

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; McAfee; InfoPath.2)

Host: 192.168.0.100:11000

Connection: Keep-Alive

 

 

 

这个是请求消息头。

        

    协议 +  地址  + 端口 +路径+ 文件

    请求头

 GET / HTTP/1.1     发送get请求

//Accept: image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/x-mfe-ipt, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */

    //支持的内容

/**

Accept-Language: zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.6,en;q=0.4,ja;q=0.2

    //支持的语言

Accept-Encoding: gzipdeflate

    //压缩方式

User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; WOW64;Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; McAfee; InfoPath.2)

Host: 192.168.0.100:11000

    主机名 和端口

Connection: Keep-Alive

 //此处有空行   


如果模拟将以上信息发送给服务器,就可以达到自定义浏览器的效果。

3.       自定义浏览器

import  java.io.*;

import java.net.*;//我的ie客户端,需要tomcat支持

public class H_06MyIE {

    public static void main(String[] args) throws Exception, IOException {

            Socket s=new Socket("192.168.0.100",8080);

            PrintWriter out=new PrintWriter(s.getOutputStream(),true);

            out.println("GET /myweb/demo.html  HTTP/1.1" );//需要一个tomcat服务器 通过服务器访问 /myweb/demo.html

            out.println("Accept: */*");

            out.println("Accept-Language: zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.6,en;q=0.4,ja;q=0.2");

            out.println("Host: 192.168.0.100:11000");

            out.println("Connection: Keep-Alive");

            out.println();

            out.println();

           

            BufferedReader bufr=new BufferedReader(new InputStreamReader(s.getInputStream()));

            String line=null;

            while((line=bufr.readLine())!=null)

            {

                System.out.println(line);

            }          

            s.close();         

    }

}


此处可以结合GUI,做一个建议IE程序,一个小文本框输入地址,一个文本区域显示得到的信息。

4.       URL&URLConnection

URI:Uniform Resource Identifier统一资源标示符。
URL:Uniform Resoure Locator统一资源定位器,也就是说根据URL能够定位到网络上的某个资源,它是指向互联网“资源”的指针。
    每个URL都是URI,但不一定每个URI都是URL。这是因为URI还包括一个子类,即统一资源名称(URN),它命名资源但不指定如何定位资源。

import  java.net.*;

import java.io.*;

public class H_08URLConnection

{

    public static void main(String[] args) throws Exception

    {

        URL url=new URL("http://www.sina.com");

        sop(url.getProtocol());

        sop(url.getHost());

        sop(url.getPort());//不指定返回-1,此时要设定默认值80

        sop(url.getPath());

        sop(url.getFile());

        sop(url.getQuery());

 

        URLConnection urlc=url.openConnection();//返回内容不带应答信息,被解析了

        //sop(urlc);

        InputStream in=urlc.getInputStream();

        byte[] buf=new byte[1024];

        int len=in.read(buf);

        sop(new String(buf,0,len));

    }

    public static void sop(Object obj)

    {

        System.out.println(obj);

    }

}


返回结果

http

www.sina.com

-1

 

 

null

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<style>@charset "utf-8";<style>body,div,span,p,iframe,a{margin:0;padding:0;outline:0}

.ad-dialog{position:absolute;z-index:998;padding:0;font-size:12px;overflow:hidden;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;box-shadow:1px 2px 2px #999;-webkit-box-shadow:1px 2px 2px #999;-moz-box-shadow:1px 2px 2px #999}.ad-dialog .title{width:100%;height:25px;line-height:25px;text-align:left;text-indent:8px;font-size:12px;font-weight:bold;color:#FFF;background:#CCC;-webkit-border-top-left-radius:4px;-moz-border-top-left-radius:4px;border-top-left-radius:4px;-webkit-border-top-right-radius:4px;-moz-border-top-right-radius:4px;border-top-right-radius:4px}.ad-dialog .icon{position:absolute;top:0;right:0;margin-right:4px}.ad-dialog .icon a{width:20px;height:20px;

 


 

5.       常见网络结构
1、C/S client/server

特点:  该结构的软件,客户端和服务端都需要编写。
            开发成本较高,维护较为麻烦。

好处:  客户端在本地可以分担一部分任务。例如,杀毒软件直接对本机文件进行杀毒。

2、B/S browser/server   

特点: 该结构的软件,只开发服务器端,不开发客户端,因为客户端直接由浏览器取代。
            开发成本相对低,维护更为简单。

 缺点:所有运算都要在服务端完成。

 

6.       练习

传输图片,服务端结合多线程

/*

        客户端

        1、创建服务端点

        2、读取客户端已有的图片数据

        3、通过socket输出流将数据发给服务端

        4、读取服务端反馈信息

        5、关闭

 */

 

package day24;

import java.io.*;

import java.net.*;

public class H_01TcpJpgClient

{

         public static void main(String[] args) throws Exception, Exception

         {

                    Socket s=new Socket(InetAddress.getLocalHost(),10008);

                    //读取文件

                    BufferedInputStream bis=new BufferedInputStream(new FileInputStream("copy.png"));

                    //输出到网络

                    PrintStream ps=new PrintStream(s.getOutputStream());

                    byte [] buf=new byte[1024];

                    int len=0;

                    while((len=bis.read(buf))!=-1)

                    {

                             ps.write(buf, 0, len);

                    }

                    s.shutdownOutput();//结束标记  否则不会结束

                    

                    BufferedInputStream bisin=new BufferedInputStream(s.getInputStream());

                    byte[] bufin=new byte[1024];

                    int  chs=bisin.read(bufin);

                    System.out.println(new String(bufin,0,chs));                 

                    bis.close();

                    s.close();

         }

}

/*

        服务端

        有个局限性,当A客户端连接上以后,被服务端获取到,服务端执行具体流程

         这时B客户端连接,只有等待。

         因为服务端还没有处理完A客户端的请求,还有玄幻回来执行下次accept方法,所以暂时获取不到B客户端请求。

 

        为了可以让多个客户端同时并发访问服务端

        将每个客户端封装到一个单独的线程中,这样就可以同时处理多个客户端请求

       

        如何定义该线程

        把客户端封装进入线程

       

 */

 

package day24;

import java.io.*;

import java.net.*;

public class H_01TcpJpgServer

{

         public static void main(String[] args) throws Exception

         {

                   ServerSocket ss=new  ServerSocket(10008);

                   while(true)//服务端一直开启

                   {                          

                            Socket s=ss.accept();

                            new Thread(new PicThread(s)).start();// 每次有连接都会创建一个线程

                   }

                  

         }

}

//所有的服务器都是这个方法,非常重要

class PicThread implements Runnable

{

         private Socket s;

         PicThread(Socket s)

         {

                   this.s=s;

         }

         public void run()

         {

                   String ip=s.getInetAddress().getHostAddress();//获取ip

                   int count=1;

                   try

                   {                          

                            BufferedInputStream bis=new BufferedInputStream(s.getInputStream());

                            //解决文件覆盖的问题

                            File file=new File(ip+count+".png");

                            while(file.exists())

                                     file=new File(ip+count+++".png");

                            PrintStream ps=new PrintStream(new FileOutputStream(file));

                            byte[] buf=new byte[1024];

                            int len=0;

                            while((len=bis.read(buf))!=-1)

                            {

                                     ps.write(buf, 0, len);

                            }

                           

                            PrintStream psout=new PrintStream(s.getOutputStream());

                            psout.write("上传成功".getBytes());             

                            ps.close();

                            s.close();

                   } catch (FileNotFoundException e)

                   {

                            e.printStackTrace();

                   } catch (IOException e)

                   {

                                     e.printStackTrace();

                   }

         }

}


 

0 0
原创粉丝点击