zoukankan      html  css  js  c++  java
  • 黑马程序员__Java网络编程

    day23、24

    1.网络通讯的要素:

    • 找到对方IP
    • 数据要发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识。为了方便称呼,该数字叫做 端口! (这是逻辑接口)
    • 定义通讯规则,这个规则就是: 协议!  国际通用协议TCP/IP  还有很多其他协议

    特殊IP:  127.0.0.1是回送地址,指默认情况下的本机地址

    常见端口: web服务器80   Tomcat服务器8080  MySQL3306

    2.传输协议有2种: TCP  UDP

    OSI模型:     应用层 表示层 对话层    传输层  网络层  数据链路层 物理层

    TCP/IP模型: 应用层        传输层  网际层  主机-网络层

    javaweb开发处于: 应用层。

    应用层的协议包括:  HTTP FTP  等

    其中传输层定义了TCP、UDP协议,  网际层定义了IP协议,   java网络编程处理的是:网络层、传输层,不经过应用层

    3.

    • IP地址:网络中设备的标识。      本机回环IP127.0.0.1   主机名:localhost
    • 端口号:用于标识进程的逻辑地址。   有效端口 0-65535, 0-1024为系统使用,即保留端口
    • 传输协议:通讯的规则。         常见协议 TCP  UDP 

    4.InetAddress 类

    该类没有构造函数,通过各种get方法获取对象。     由主机名+地址组成,如: www.baidu.com/111.13.100.92

            InetAddress ip = InetAddress.getLocalHost();    
            System.out.println(ip);
            System.out.println(ip.getHostAddress());
            System.out.println(ip.getHostName());
            static     InetAddress getLocalHost() //返回本地主机。         
            String        getHostAddress()// 返回对象的原始IP地址 
            String         getHostName()   // 返回对象的主机名 
            
            static  InetAddress     getByName(String host)  //返回指定主机的一个IP对象        
            static  InetAddress[]   getAllByName(String host) //返回指定主机的所有IP对象
            static  InetAddress     getByAddress(byte[] addr) 
     
            InetAddress ip = InetAddress.getLocalHost();    
            System.out.println(ip);  //输出tyh-PC/192.168.252.1
            System.out.println(ip.getHostAddress());  //输出192.168.252.1
            System.out.println(ip.getHostName());  //输出tyh-PC
            
            //给定主机名,会去联机查找其ip地址,返回主机名/地址
            //找不到时,抛出UnknownHostException异常
            InetAddress ip=InetAddress.getByName("www.qq.com");
            System.out.println(ip);//www.qq.com/111.30.132.101
            
            //给定ip地址得到ip对象,这种方式不会去查找name,仅仅创建一个ip对象
            //尽管这是百度ip,因为不联网查找,不知道主机名
            byte[] by = {111,13,100,92};    
            InetAddress ip = InetAddress.getByAddress(by);
            System.out.println(ip.getHostName());//111.12.100.92
            //一台主机可以有多个IP地址
            InetAddress[] is = InetAddress.getAllByName("www.baidu.com");
            for(InetAddress i:is)
                System.out.println(i);//www.baidu.com/111.13.100.91
                                      //www.baidu.com/111.13.100.92

    5.TCP和UDP:

    UDP协议特点:  User Datagram Protocol的简称, 中文名是用户数据报协议

    • 将数据及源和目的封装成数据包中,不需要建立连接
    • 每个数据报的大小限制在  64K
    • 因无连接,是不可靠协议
    • 不需要建立连接,速度快
    • 常用于: 视频传输 音频传输

    TCP协议特点:

    • 建立连接,形成建立数据的通道
    • 在连接中进行大数据量传输
    • 通过三次握手完成连接,是可靠协议
    • 必须建立连接,效率会稍低

    6. Socket   java网络编程指的就是Socket编程,Socket是为网络服务提供的一种机制

    • 通信的两端都有Socket,网络通信其实就是Socket的通信
    • 数据在两个Socket间通过IO传输

    7. UDP传输

    定义UDP发送端:

    • 建立Socket服务。
    • 提供数据,并将数据封装到数据包中。
    • 通过Socket服务中的发送功能,将数据包发出去。
    • 关闭资源。

    定义UDP接收端:

    • 定义Socket服务,需要监听一个端口。其实就是给这个接收网络应用程序定义数字标识。
    • 定义数据包,用于存储接收的字节数据。  数据包对象的方法可以提取指定的数据
    • 通过Socket服务的receive方法将接收到的数据存入已经定义好的数据包中。
    • 通过数据包对象的特有功能,将这些数据取出
    • p关闭资源。
    class UdpSend {
    
        public static void main(String[] args)throws Exception {
            //1.创建socket服务,通过DatagramSocket对象
            //可以不指定端口号,系统会随机分配一个
            //一台机器的一个端口在同一时间只能被一个程序占用,否则抛出Bind绑定异常
            DatagramSocket ds = new DatagramSocket(9000);
            
            //2.确定数据,封装成数据包
            byte[] buf = "udp 发送开始了。。。。".getBytes();
            byte[] byip = {112,37,77,68};//本机临时ip
            byte[] byip2 = {127,0,0,1};  //本机回环ip
            DatagramPacket dp = new DatagramPacket(buf, buf.length, 
                    InetAddress.getByAddress(byip2), 10000);
            //当ip的后面是255时,代表广播地址,可以把数据广播到局域网
            
            //3.通过socket服务,将已有的数据包发送出去
            ds.send(dp);
            
            //4.关闭资源
            ds.close();
        }
    
    }
    • class UdpRec { public static void main(String[] args)throws Exception { //1.创建socket,这里要指定需要监听的端口 DatagramSocket ds = new DatagramSocket(9999); //定义数据包,用于存储数据 byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); //通过服务的receive方法将收到的数据存入数据包中。 //receive是一个阻塞式方法,没收到数据,就会一直wait ds.receive(dp); //通过数据包的方法取出包中的数据 String ip = dp.getAddress().getHostAddress(); String data = new String(dp.getData(),0,dp.getLength()); int port = dp.getPort(); System.out.println(ip+"::"+data+"::"+port); //关闭资源 ds.close(); } }

    8.TCP传输:

    不同于UDP,分为客户端、服务端,  Socket、 ServerSocket

    客户端:

    • 创建Socket服务,指定要连接的主机和端口
    • 使用Socket的输出流发送数据
    • 关闭Socket对象

    服务端:

    • 建立服务端的Socket服务,ServerSocket,并监听一个端口
    • 获取连接过来的客户端对象,通过accept方法
    • 使用客户端对象的流读取和发送数据
    • 关闭Socket对象,关闭服务端对象
    class TcpClient {
    
        public static void main(String[] args) throws Exception{
            //创建客户端的Socket服务,指定目的主机和端口
            Socket s = new Socket("127.0.0.1",9999);
            
            //为了发送数据,应该获取Socket流中的输出流
            OutputStream out = s.getOutputStream();
            
            out.write("网络编程".getBytes());
            
            s.close();        
        }
    
    }
    class TcpServer {
    
        public static void main(String[] args)throws Exception {
            // 建立服务端Socket服务,并监听一个端口
            ServerSocket ss = new ServerSocket(9999);
            //通过accept方法来获取连接过来的客户端对象
            Socket s = ss.accept();
            System.out.println("连接成功");
            
            //获取客户端对象发送过来的数据,
            InputStream in = s.getInputStream();
             
            byte[] buf = new byte[1024];
            int len =  in.read(buf);
            System.out.println(new String(buf,0,len));
                    
            s.close();
            ss.close();
        }
    
    }

     ServerSocket类有一种特殊构造方法:

    ServerSocket(int port, int backlog)
    backlog - 队列的最大长度, 即能连接到服务器的最多客户端个数。

    9.为了让多个客户端同时并发访问服务端,服务端最好的做法是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求。

    class PicClient {
    
        public static void main(String[] args)throws Exception {
            // TODO Auto-generated method stub
            Socket s = new Socket("127.0.0.1", 10000);
            
            BufferedInputStream bufr = new BufferedInputStream(new FileInputStream("abc.jpg"));
            OutputStream out = s.getOutputStream();
            int len=0;
            byte[] buf = new byte[1024];
            while((len=bufr.read(buf))!=-1)
                out.write(buf,0,len);
            s.shutdownOutput();
            
            
            InputStream in = s.getInputStream();
            byte[] bufIn = new byte[1024];
            int num = in.read(bufIn);
            System.out.println(new String(bufIn,0,num));
            
            bufr.close();
            s.close();
        }
    
    }
    class PicServer2 {
    
        public static void main(String[] args)throws Exception {
            ServerSocket ss= new ServerSocket(9980);
                
            while (true) {
                Socket s = ss.accept();
                new Thread(new PicThread(s)).start();
            }    
        }
    }
    class PicThread implements Runnable {
    
        private Socket s;
        public PicThread(Socket s){
            this.s = s;
        }
            
        public void run() {    
            int count = 0;
            try {
                String ip = s.getInetAddress().getHostAddress();
                System.out.println(ip+"。。连接成功");
                
                File file = new File(ip+"("+(count)+")"+".jpg");
                while(file.exists())
                    file = new File(ip+"("+(count++)+")"+".jpg");
                
                InputStream in = s.getInputStream();            
                FileOutputStream fos = new FileOutputStream(file);
                byte[] buf = new byte[1024];
                int len = 0;
                while((len=in.read(buf))!=-1){
                    fos.write(buf,0,len);    
                }
                
                OutputStream out = s.getOutputStream();
                out.write("上传成功".getBytes());
                
                fos.close();
                s.close();
                
            } catch (Exception e) {
                throw new RuntimeException("上传失败");
            }
        }
    
    }

    10.可以使用浏览器登录下面的服务端,也可以用telnet远程登录命令

    class ServerDemo {
    
        public static void main(String[] args)throws Exception {
            //自定义服务端,使用浏览器登录
            ServerSocket ss = new ServerSocket(10000);    
            System.out.println("启动成功");
            Socket s = ss.accept();
            System.out.println("接收到"+s.getInetAddress().getHostAddress());
            PrintWriter pw = new PrintWriter(s.getOutputStream(),true);    
            pw.println("<font color='red'>客户端你好</font>");
            
            s.close();
            ss.close();
        }
    }

    11.可以自定义浏览器

    浏览器软件的强大之处在于包含了很多解析引擎,比如Html解析引擎、CSS解析引擎、JavaScript解析引擎。

    浏览器会首先向服务器发生一个头文件:

    //chrome浏览器发送的
    GET / HTTP/1.1
    Host: 127.0.0.1:10000
    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 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36
    Accept-Encoding: gzip, deflate, sdch
    Accept-Language: zh-CN,zh;q=0.8
    
    
    //IE浏览器发送的
    GET / HTTP/1.1
    Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*
    Accept-Language: zh-CN
    User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Win64; x64; Trident/4.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E; Media Center PC 6.0; Tablet PC 2.0)
    UA-CPU: AMD64
    Accept-Encoding: gzip, deflate
    Host: 127.0.0.1:10000
    Connection: Keep-Alive
    
    
    -------------------------------

    Http现在有2个版本,1.1是最新版本。

    Keep-Alive表示IE与服务器之间会一直保持连接,但是如果一段时间没有响应,会超时,自动断开连接。 也可以设置为  closed

    下面是自己实现的简单IE:

    public class MyIE {
    
        public static void main(String[] args)throws Exception {
            // 
            Socket s = new Socket("127.0.0.1",8080);
            
            PrintWriter wr = new PrintWriter(s.getOutputStream(),true);
            wr.println("GET /tyh/demo.html HTTP/1.1");
            wr.println("Accept:*/*");
            wr.println("Accept-Language: zh-CN");
            wr.println("Host: 127.0.0.1:8080");
            wr.println("Connection: Keep-Alive");
            //这里必须跟2个空行! 这是请求头消息的结束格式
            wr.println();
            wr.println();
            
            BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));
            String line = null;
            while((line=bufr.readLine())!=null)
                System.out.println(line);
            
            s.close();
        }

    连接TomCat服务器之后,服务器也会发一个头消息:

    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    Accept-Ranges: bytes
    ETag: W/"7247-1422441251130"
    Last-Modified: Wed, 28 Jan 2015 10:34:11 GMT
    Content-Type: text/html
    Content-Length: 7247
    Date: Tue, 24 Feb 2015 09:27:16 GMT

    200是响应状态码,代表ok。

    12.URL类:

    • URL组成: 协议名://服务器名称(或IP地址):端口号/路径和文件名?查询
    • URL 可选择指定一个“端口”,它是用于建立到远程主机 TCP 连接的端口号。如果未指定该端口号,则使用协议默认的端口。例如,http 协议的默认端口为 80。

    URL的常见构造方式:

    URL(String spec)
    URL(String protocol, String host, int port, String file)
    URL(String protocol, String host, String file)

            URL url = new URL("http://cart.mi.com/cart/?你是谁?");
            System.out.println(url.getProtocol());//http
            System.out.println(url.getHost());//cart.mi.com
            System.out.println(url.getPort());//-1
            System.out.println(url.getPath());///cart/
            System.out.println(url.getFile());///cart/?你是谁?
            System.out.println(url.getQuery());//你是谁?
            

    URLConnection类是一个抽象类

    • 它是所有表示应用程序与URL之间通信连接的类的父类(super class),该类的实例可以用来对由URL引用的资源进行读取和写入操作。
    • 它工作在应用层,将服务器发回的Http协议头信息隐藏
    • 它提供了方法,可以查看服务器发回的头信息
    • URLConnection类底层依赖Socket类实现网络连接,它比Socket类提供了更便利的网络连接抽象
            URL url2 = new URL("http://127.0.0.1:8080/tyh/demo.html");
            URLConnection openConnection = url2.openConnection();
            System.out.println(openConnection);
            InputStream in = openConnection.getInputStream();
            //打印  sun.net.www.protocol.http.HttpURLConnection:http://www.bjt.name/2013/09/emacs-configure/
            //也可以用in = url2.openStream()
            //该方法是下面方法的缩写:   openConnection().getInputStream()
    
        
            byte[] buf = new byte[1024];    
            int len = in.read(buf);
            System.out.println(new String(buf,0,len));        
            in.close();

    13.当向浏览器输入一个地址时,浏览器先将地址解析一下,得到服务器名,一般输入的服务器名是域名(Domain Name),如:www.baidu.com

    必须先将域名解析成ip地址,需要域名解析服务器(DNS)。

    解析之前,会先搜索C:WindowsSystem32driversetc下的hosts文件,查看是否匹配,然后再去查询DNS服务器。


    一个IP地址可以对应多个域名,一个域名也可以对应多个IP地址。

  • 相关阅读:
    elasticsearch配置文件
    elk+filebeat源码安装
    logstash配置文件
    kibana配置文件
    filebeat配置文件
    老年人和棒子(李敖)
    Linux下傻瓜式安装配置V_2_r_a_y
    【有关学习Q国的自动化工具的学习思路】
    有关在使用aireplay-ng处理5Ghz频段的wifi时出现“No such Bssid available”的解决方法
    springboot整合日志logback
  • 原文地址:https://www.cnblogs.com/tyh2014/p/4285216.html
Copyright © 2011-2022 走看看