`
new_Line
  • 浏览: 9761 次
  • 性别: Icon_minigender_1
最近访客 更多访客>>
社区版块
存档分类
最新评论

黑马程序员_java 网络编程

 
阅读更多

------- android培训java培训、期待与您交流! ----------

网络编程概述:
        计算机网络:
        是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,
        实现资源共享和信息传递的计算机系统。
    计算机网络的主要功能:
        1:资源共享
        2:信息传输与集中处理
        3:均衡负荷与分布处理
        4:综合信息服务
    计算机网络的分类:
        局域网(LAN)、城域网(MAN)、广域网(WAN)。Internet可视为世界最大的广域网
    网络模型:
        OSI参考模型:
            计算机网络之间以何种规则进行通信,就是网络模型研究问题。国际标准化组织ISO与1978年提出"开放系统互连参考模型",
            即OSI(Open System Interconnection)。OSI参考模型把计算机网络分成物理层、数据链路层、网络层、传输层、会话层、
            表示层、应用层。OSI参考模型已成为各种计算机网络结构的参考标准。
        TCP/IP协议模型:
            按TCP/IP协议模型,网络被分成物理+数据链路、网络层、传输层、应用层。TCP/IP协议模型和OSI参考模型有着大致的对应关系。
                --------------------------
                应用层   
                --------
                表示层         应用层
                --------
                会话层
                --------------------------
                传输层     传输层
                --------------------------
                网络层     网络层
                --------------------------
                数据链路层
                --------    物理+数据链路
                物理层
               ----------------------------
               OSI分层模型和TCP/IP分层模型的对应关系
        网络通信的三要素:
            1:IP地址:
                IP地址用于唯一的标识网络中的一个通信实体,
                IP地址的分类:
                    IP地址的分类:
                    A类:1.0.0.1--- 127.255.255.254   
                        (1)10.X.X.X是私有地址(私有地址就是在互联网上不使用,而被用在局域网络中的地址)
                        (2)127.X.X.X是保留地址,用做循环测试用的。
                    B类:128.0.0.1---191.255.255.254   
                        172.16.0.0---172.31.255.255是私有地址。169.254.X.X是保留地址。
                    C类:192.0.0.1---223.255.255.254   
                        192.168.X.X是私有地址
                    D类:224.0.0.1---239.255.255.254    
                    E类:240.0.0.1---247.255.255.254   
                如何在查看本机的ip地址:打开命令行,输入ipconfig
                测试网络连接是否良好:打开命令行,输入ping ip地址
                本地回环地址:127.0.0.1
                网络地址:xxx.xxx.xxx.0
                广播地址:xxx.xxx.xxx.255
                案例体现:
                    import java.io.IOException;
                    import java.net.InetAddress;
                    import java.net.UnknownHostException;
                    /**
                     * java提供了InetAddress类来代表IP地址,InetAddress类没用提供构造器,而是通过静态的构造方法来获取InetAddress实例。
                     *     1:static InetAddress getByName(String host):在给定主机名或者ip地址的情况下,获取InetAddress的实例
                     *      2:static InetAddress getLocalHost() 返回本地主机所对应的InetAddress实例
                     *    3:static InetAddress[] getAllByName(String host) 在给定主机名的情况下,根据系统上配置的名称服务返回其 IP 地址
                     * InetAddress还提供了获取InetAddress实例对应的IP地址和主机名的方法:
                     *     1: String getHostAddress() 返回 IP 地址字符串(以文本表现形式)。
                     *     2: String getHostName()  获取此 IP 地址的主机名。
                     *     3:String getCanonicalHostName()  获取此 IP 地址的完全限定域名。
                     *     4: boolean isReachable(int timeout) 测试是否可以达到该地址。 
                     * */
                    public class InetAddressTest {
                        public static void main(String[] args) throws IOException {
                            //获取本机的InetAddress实例
                            InetAddress ia1 = InetAddress.getLocalHost();
                            //获取本机的IP地址
                            System.out.println("我的IP地址是:" + ia1.getHostAddress());
                            //获取本机的主机名
                            System.out.println("我的主机名是:" + ia1.getHostName());
                            //通过主机名创建对象
                            InetAddress ia2 = InetAddress.getByName("113.251.70.43");
                            System.out.println("该计算机的主机名是:" + ia2.getHostName());
                            System.out.println("该计算机的ip地址是:" + ia2.getHostAddress());
                        }
                    }
            2:端口号:
                在明确IP地址的情况下,用于表示数据具体交给哪个通信程序处理。
                因此,端口号就是应用程序与外界交流的出入口。
                端口号的分类:
                    1:公认端口:从0到1023,它们紧密绑定一些特定的服务
                    2:注册端口:从1024到49151,应用程序一般使用这个范围内的端口
                    3:动态或私有端口:从49152到65535,这些端口是应用程序使用的动态端口。
                    常见的端口:
                        web服务:80
                        web服务器:默认是8080
                        数据库: 3306

            3:传输协议:
                常用的TCP协议和UDP协议
                UDP协议:是一种面向非连接的协议,不需要建立连接。将数据源和目的封装成数据包中,
                    每个数据报的大小限制在64k;因无连接,所以是不可靠协议;速度快
                   作用:完成网络数据流和数据报之间的转换。在信息的发送端,UDP协议将网络数据流
                    封装成数据报,然后将数据发送出去;在信息的接收端,UDP协议将数据报转换成
                    实际的数据内容。
                   应用场景:聊天、视频会话、桌面共享等。
                TCP协议:建立连接,形成传输数据的通道;在连接中进行大数据量传输;通过三次握手
                    完成连接,是可靠协议;效率会稍低
                UDP协议和TCP协议直接位于IP协议之上。IP协议属于网络层协议,UDP协议和TCP协议都属于传输层协议
        Socket:
            Socket就是为网络服务提供的一种机制,通信的两端都有Socket,网络通信其实就是Socket之间的
            通信,数据在两个Socket之间通过IO流传输
        基于UDP协议的网络编程:
            使用DatagramSocket发送、接收数据:
                Java使用DatagramSocket代表UDP协议的Socket,DatagramSocket本身只是码头,不维护状态,不能产生IO流
                它的唯一作用就是接收和发送数据报,Java使用DatagramPacket来代表数据报,DatagramSocket接收和发送
                数据都是通过DatagramPacket对象来完成的
            DatagramSocket的构造器:
                 DatagramSocket(int port) 创建数据报套接字并将其绑定到本地主机上的指定端口。接收端和发送端均可使用
                 DatagramSocket()  构造数据报套接字并将其绑定到本地主机上任何可用的端口。仅用于发送端
                 DatagramSocket(int port, InetAddress laddr) 创建数据报套接字,将其绑定到指定的本地地址,指定端口
            DatagramSocket的方法:
                 void receive(DatagramPacket p) 接收数据报,该方法会阻塞调用该方法的线程,直到接收到数据为止
                 void send(DatagramPacket p) 发送数据报
            DatagramPacket的构造器:
                DatagramPacket(byte[] buf, int length) 先创建一个空数组,用来接收长度为 length 的数据包。接收存储数据
                DatagramPacket(byte[] buf, int length, InetAddress address, int port)
                            构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
            DatagramPacket的方法:
                 byte[] getData() 返回数据缓冲区。
                 InetAddress getAddress() 返回某台机器的 IP 地址,此数据报将要发往该机器或者是从该机器接收到的。
                 int getPort() 返回某台远程主机的端口号,此数据报将要发往该主机或者是从该主机接收到的。
                 int getLength() 返回将要发送或接收到的数据的长度。
            案例体现一:
                /*
                 * Description:
                 *   发送端从键盘录入数据,在接收端显示,模拟一个简单的聊天小程序
                 */
                package com.itheima.sent;
                import java.io.BufferedReader;
                import java.io.IOException;
                import java.io.InputStreamReader;
                import java.net.DatagramPacket;
                import java.net.DatagramSocket;
                import java.net.InetAddress;
               
                public class SentDemo2 {
                    public static void main(String[] args) throws IOException {
                        //1.创建UDPSocket服务对象
                        DatagramSocket ds = new DatagramSocket(8888);
                        //2.确定数据,将数据打包
                        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                        String line = null;
                        while((line = br.readLine()) != null)
                        {
                            //自定义结束标记
                            if("886".equals(line))
                            {
                                break;
                            }
                            DatagramPacket dp = new DatagramPacket(line.getBytes(), line.length(), InetAddress.getByName("192.168.1.101"), 10000);
                            //3.发送数据
                            ds.send(dp);
                        }
                        //4.关闭资源
                        ds.close();
                    }
                }
                package com.itheima.receive;
                import java.net.DatagramPacket;
                import java.net.DatagramSocket;
                public class ReceiveDemo1 {
                    public static void main(String[] args) throws Exception {
                        //步骤:
                        //1.创建UDP的Socket服务
                        DatagramSocket ds = new DatagramSocket(10000);
                        while(true){
                            //2.定义一个空的数据报,因为要接收存储数据,
                            byte[] bys = new byte[1024];
                            DatagramPacket dp = new DatagramPacket(bys, bys.length);
                            //3.通过UDP服务的receive()方法,将数据存入数据包中
                            ds.receive(dp);
                            //4.通过数据报的方法,解析数据
                            String data = new String(dp.getData(), 0, dp.getLength());
                            System.out.println("ip:" + dp.getAddress().getHostAddress() + "端口号:" + dp.getPort() + "  :" + data);
                            //5.关闭资源
                        }
                    }
                }
            案例体现二:
                /*
                    对上面程序进行改进,加入多线程
                 */
                import java.io.IOException;
                import java.net.DatagramSocket;

                import com.itheima.receive.ReceiveThread;
                import com.itheima.sent.SentThread;

                public class ChatRoom {
                    public static void main(String[] args) throws IOException {
                        DatagramSocket ds1 = new DatagramSocket();
                        DatagramSocket ds2 = new DatagramSocket(12306);
                       
                        SentThread st = new SentThread(ds1);
                        ReceiveThread rt = new ReceiveThread(ds2);
                       
                        st.start();
                        rt.start();
                    }
                }
                import java.io.BufferedReader;
                import java.io.IOException;
                import java.io.InputStreamReader;
                import java.net.DatagramPacket;
                import java.net.DatagramSocket;
                import java.net.InetAddress;
                import java.net.UnknownHostException;

                public class SentThread extends Thread{
                    private DatagramSocket ds;
                    public SentThread(DatagramSocket ds)
                    {
                        this.ds = ds;
                    }
                    public void run()
                    {
                        BufferedReader br = null;
                        try {
                            br = new BufferedReader(new InputStreamReader(System.in));
                            String line = null;

                                while((line = br.readLine()) != null)
                                {
                                    DatagramPacket dp = new DatagramPacket(line.getBytes(), line.length(), InetAddress.getByName("192.168.1.101"), 12306);
                                    ds.send(dp);
                                    if("886".equals(line))
                                        break;
                                }


                               
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }finally
                        {
                            try {
                                br.close();
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }

                            ds.close();
                        }
                    }
                }
                import java.io.IOException;
                import java.net.DatagramPacket;
                import java.net.DatagramSocket;

                public class ReceiveThread extends Thread{
                    private DatagramSocket ds;
                    public ReceiveThread(DatagramSocket ds)
                    {
                        this.ds = ds;
                    }
                    public void run()
                    {
                        try {
                            while(true){
                                byte[] bys = new byte[1024];
                                DatagramPacket dp = new DatagramPacket(bys, bys.length);

                                    ds.receive(dp);
                               
                                String data = new String(dp.getData(), 0, dp.getLength());
                                System.out.println("ip:" + dp.getAddress().getHostAddress() + "*****" + data);
                            }
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
        基于TCP协议的网络编程:
            使用SeverSocket创建TCP服务器端:
                Java中能够接收其他通信实体连接请求的类是ServerSocket,SeverSocket对象用于监听来自客户端的Socket连接,
                如果没有连接,它将一直处于等待状态。
                SeverSocket的构造方法:
                    ServerSocket(int port) 创建绑定到特定端口的服务器套接字。
                SeverSocket的方法:
                     Socket accept() :如果接收到一个客户端Socket的连接请求,
                        该方法将返回一个与客户端Socket对应的Socket对象。否则该方法将一直处于等待状态,线程被阻塞。
            使用Socket客户端进行通信:
                客户端可以使用Socket的构造器来连接到指定的服务器。
                Socket的构造方法:
                    Socket(InetAddress address, int port) 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
                        如果没有指定,系统默认使用本地主机的IP地址,默认分配端口
                Socket的方法:
                    InputStream getInputStream() 返回该Socket对象对应的输入流,让程序通过该输入流向Socket读取数据
                    OutputStream getOutputStream() 返回该Socket对象对应的输出流,让程序通过该流向Socket中写入数据
                     void shutdownOutput() 禁用此套接字的输出流。告诉服务端数据已写完
                    案例体现一:
                        import java.io.BufferedReader;
                        import java.io.IOException;
                        import java.io.InputStreamReader;
                        import java.io.PrintWriter;
                        import java.net.Socket;
                        /*
                         *TCP客户端:
                         *    通过查阅API文档发现,在Socket对象建立时,就指定连接的主机,
                         *    因为TCP是面向连接的,所以在建立Socket服务时,就要有服务端的存在,
                         *     并且连接成功后,才能进行数据传输
                         *1:建立客户端的Socket服务,并明确要连接的服务器。
                         *2:如果连接建立成功,就表明,已经建立了数据传输的通道.
                         *    就可以在该通道通过IO进行数据的读取和写入.
                         *    该通道称为Socket流,Socket流中既有读取流,也有写入流.
                         *3:通过Socket对象的方法,可以获取这两个流
                         *4:通过流的对象可以对数据进行传输
                         *5:如果传输数据完毕,关闭资源
                        */
                        public class ClientDemo1 {
                            public static void main(String[] args) throws IOException {
                                //1:建立客户端的Socket服务,并明确要连接的服务器。
                                Socket s = new Socket("192.168.1.101", 10001);
                                //2:向管道写入
                                PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
                               
                                pw.println("haha,我来了");
                                BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
                                String line = br.readLine();
                                System.out.println(line);
                                //关闭资源
                                s.close();
                            }
                        }
                        import java.io.BufferedReader;
                        import java.io.IOException;
                        import java.io.InputStreamReader;
                        import java.io.PrintWriter;
                        import java.net.ServerSocket;
                        import java.net.Socket;
                        /*
                        TCP服务端:
                        1:建立服务器端的socket服务,需要一个端口
                        2:服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信
                        3:通过客户端的获取流对象的方法,读取数据或者写入数据
                        4:如果服务完成,需要关闭客户端,然后关闭服务器,但是,一般会关闭客户端,不会关闭服务器,因为服务端是一直提供服务的
                        */
                        public class ServerDemo1 {
                            public static void main(String[] args) throws IOException {
                                // 建立服务器的Socket对象,指定监听端口
                                ServerSocket ss = new ServerSocket(10001);
                                // 返回当前连接的客户端对象
                                Socket s = ss.accept();
                                // 获取输入流对象
                                BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
                                String line = br.readLine();
                                System.out.println("ip:" + s.getInetAddress().getHostAddress() + "   :" + line);
                                //获取输出流对象,给客户端反馈
                                PrintWriter pw = new PrintWriter(s.getOutputStream());
                                pw.println("哈哈,我走了");
                                //关闭资源
                                s.close();
                                ss.close();
                            }
                        }
           
                    案例体现二:
                    /*
                     * 功能:向服务器并发上传图片
                     *    为了让多个客户端同时访问服务端,那么最好就把每一个客户端封装到一个单独的线程
                     *    就可以同时处理多个客户端的请求
                     * 如何定义线程呢?
                     *    只要明确每一个客户端要在服务端执行的代码即可
                     * */
                    import java.io.BufferedInputStream;
                    import java.io.BufferedOutputStream;
                    import java.io.BufferedReader;
                    import java.io.FileInputStream;
                    import java.io.FileOutputStream;
                    import java.io.IOException;
                    import java.io.InputStreamReader;
                    import java.net.Socket;
                    /*
                     * 功能:向服务器上传图片
                     * 1:服务端点
                     * 2:从客户端读取图片
                     * 3:通过Socket输出流发送给服务端
                     * 4:从服务端获取反馈信息
                     * 5:关闭资源
                     * */
                    public class ClientDemo3 {
                        public static void main(String[] args) throws IOException {
                            //创建Socket对象
                            Socket s = new Socket("192.168.1.101", 10011);
                            //封装数据源
                            BufferedInputStream bis = new BufferedInputStream(new FileInputStream("K:\\pic.jpg"));
                           
                            //封装目的地
                            BufferedOutputStream pw = new BufferedOutputStream(s.getOutputStream());
                            byte[] bys = new byte[1024];
                            int len = 0;
                            while((len = bis.read(bys)) != -1)
                            {
                                pw.write(bys, 0, len);
                                pw.flush();
                            }
                            //告诉服务端数据已写完
                            s.shutdownOutput();
                            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
                            String line = br.readLine();
                            System.out.println(line);
                            bis.close();
                            s.close();
                        }
                    }
                    import java.io.BufferedInputStream;
                    import java.io.BufferedOutputStream;
                    import java.io.File;
                    import java.io.FileOutputStream;
                    import java.io.IOException;
                    import java.io.PrintWriter;
                    import java.net.Socket;

                    public class PicServerThread implements Runnable{
                        private Socket s;
                        public PicServerThread(Socket s)
                        {
                            this.s = s;
                        }
                        @Override
                        public void run() {
                            String ip = s.getInetAddress().getHostAddress();
                            try {
                                int count = 1;
                                System.out.println(ip + "  进来啦");
                                File file = new File("k:\\" + "pic" + count + ".jpg");
                                while(file.exists()){
                                    file = new File("k:\\" + "pic" + (count++) + ".jpg");
                                }
                               
                                BufferedInputStream br = new BufferedInputStream(s.getInputStream());
                                BufferedOutputStream pw = new BufferedOutputStream(new FileOutputStream(file));
                                byte[] bys = new byte[1024];
                                int len = 0;
                                while((len = br.read(bys)) != -1)
                                {
                                    pw.write(bys, 0, len);
                                    pw.flush();
                                }
                                PrintWriter pw1 = new PrintWriter(s.getOutputStream());
                                pw1.println("上传成功");
                                pw1.flush();
                                pw.close();
                                s.close();
                            } catch (IOException e) {
                                throw new RuntimeException(ip + "上传失败");
                            }
                        }
                    }
                    import java.io.IOException;
                    import java.net.ServerSocket;
                    import java.net.Socket;

                    public class SeverDemo4 {
                        public static void main(String[] args) throws IOException {
                            ServerSocket ss = new ServerSocket(10011);
                            while(true)
                            {
                                Socket s = ss.accept();
                                new Thread(new PicServerThread(s)).start();
                            }
                        }
                    }

------- android培训java培训、期待与您交流! ----------

0
4
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics