美文网首页
【Java基础】java网络编程

【Java基础】java网络编程

作者: 灰色孤星 | 来源:发表于2018-10-16 00:05 被阅读0次

    源代码:https://gitee.com/AgentXiao/NetProgram

    一、几个概念

    1、网络

    将不同区域的计算机连接到一起。简单氛围局域网、城域网、互联网

    2、地址

    即ip地址,确定计算机在网络上的一个绝对位置。相当于城市中的一栋房子

    3、端口

    区分计算机软件的。例如计算机安装了QQ、微信等不同软件,使用端口号实现不同的软件访问不同的服务器。相当于房子的窗户,每个窗户对应不同的软件。
    特点:(1)2个字节 0-65535 共65536个
    (2)1024以下的不要使用,因为是预留给计算机和各大厂商的,例如http -> 80,ftp -> 21

    4、资源定位

    统一资源定位符URL
    统一资源URI

    5、数据的传输

    1)协议
    TCP协议(transfer control protocol 传输控制协议)类比电话(面向连接,需要连接后才能通信)类似于三次握手,安全可靠但是效率低下
    UDP协议(user datagram protocol 用户数据包协议)类比短信(非面向连接,不需要建立连接也可以通信)不安全但是效率高
    2)传输
    先封装、后拆封

    二、类

    底层还是流。学习网络编程实际上还是学习类的使用。

    1、InetAddress:封装IP和DNS

    这个类是没有构造方法的(构造),但是提供了静态方法用户创建InetAddress对象。创建InetAddress对象的三种方式及常用方法如下:

            //InetAddress类没有构造方法,需要通过调用静态方法进行创建
    
            //根据getLocalHost方法创建InetAddress对象
            InetAddress addr = InetAddress.getLocalHost();//这是一个静态方法
            System.out.println(addr.getHostName());//获得计算机名
            System.out.println(addr.getHostAddress());//获得IP地址
    
            //根据域名创建InetAddress对象
            addr = InetAddress.getByName("www.baidu.com");
            System.out.println(addr.getHostName());//获得计算机名
            System.out.println(addr.getHostAddress());//获得IP地址
    
            //根据IP地址创建InetAddress对象
            addr = InetAddress.getByName("183.232.231.172");
            System.out.println(addr.getHostName());//获得计算机名。如果没有解析,则返回自身
            System.out.println(addr.getHostAddress());//获得IP地址
    

    2、InetSocketAddress:封装端口

    这个类相比于InetAddress还封装了端口号:

            //通过构造方法创建InetSocketAddress对象,指定地址和端口
            InetSocketAddress isa = new InetSocketAddress("localhost",9999);
            //hostname是字符串时实际上也是调用了InetAddress.getByName("127.0.0.1")
            //InetSocketAddress isa = new InetSocketAddress(InetAddress.getByName("127.0.0.1"),9999);
            System.out.println(isa.getPort());//获得端口
            System.out.println(isa.getHostName());//获得计算机名称
    
            InetAddress addr = isa.getAddress();
            System.out.println(addr.getHostAddress());//获得IP地址
            System.out.println(addr.getHostName());//获得计算机名
    

    3、URL

    URI(Uniform resource identifier)统一资源标识符,用来唯一的标识一个资源。
    URL(Uniform Resource Locator)统一资源定位器,它是一种具体的URI 。
    URL由四部分组成:协议+存放资源的主机名称+端口+资源文件名
    java中的URL类:
    1)常用构造方法
    URL(String spec) :绝对路径构建
    URL(URL context, String spec) :相对路径构建
    2)常用方法

            //绝对路径构建
            URL url = new URL("http://www.baidu.com:80/index.jsp#aa?username=jack");
            //相对路径构建
            //URL url = new URL("http://www.baidu.com:80/a/");
            //url = new URL(url,"b.jsp");
            System.out.println(url.toString());
    
            //常用方法
            System.out.println("协议"+url.getProtocol());
            System.out.println("域名"+url.getHost());
            System.out.println("端口"+url.getPort());
            System.out.println("资源"+url.getFile());
            System.out.println("相对路径"+url.getPath());
            System.out.println("锚点"+url.getRef());
            System.out.println("参数"+url.getQuery());//如果存在锚点则返回null,因为参数被当做了锚点的一部分
        }
    }
    

    3)流 openStream

            URL url = new URL("http://www.baidu.com");//默认资源
    
            //获得资源 网络流
            InputStream is = url.openStream();
    
            //输出:会乱码
    //        byte[] flush = new byte[1024];
    //        int len = 0;
    //        while(-1 != (len=is.read(flush))){
    //            System.out.println(new String(flush,0,len));
    //        }
    //        is.close();
    
            //输出,不乱码
    //        BufferedReader bf = new BufferedReader(new InputStreamReader(url.openStream(),"utf-8"));
    //        String msg = null;
    //        while((msg = bf.readLine()) != null){
    //            System.out.println(msg);
    //        }
    //        bf.close();
    
    
            //输出到本地
            BufferedReader bf = new BufferedReader(new InputStreamReader(url.openStream(),"utf-8"));
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("baidu.html"),"utf-8"));
            String msg = null;
            while((msg = bf.readLine()) != null){
                bw.append(msg);
                bw.newLine();
            }
            bw.flush();
    
            bw.close();
            bf.close();
    

    4、UDP通信

    以数据为中心 非面向连接 不安全 数据可能丢失 效率高

    客户端
    1)创建客户端 DatagramSocket 类+指定端口
    2)准备数据 字节数组
    3)打包 DatagramPacket + 服务器地址及端口
    4)发送
    5)释放资源

            //1、创建服务器端 + 端口
            DatagramSocket server = new DatagramSocket(8888);
            //2、准备接收容器
            byte[] contains = new byte[1024];
            //3、封装成包
            DatagramPacket packet = new DatagramPacket(contains,contains.length);
            //4、接收数据
            server.receive(packet);
            //5、分析数据
            byte[] data = packet.getData();
            int len = packet.getLength();
            System.out.println(new String(data,0,len));
            //6、释放资源
            server.close();
    

    服务器端
    1)创建服务端 DatagramSocket 类+指定端口
    2)准备接收容器 字节数组 封装 DatagramPacket
    3)包 接收数据
    4)分析
    5)释放资源

            //1、创建客户端 + 端口(同一台机器端口号不能重复)
            DatagramSocket client = new DatagramSocket(6666);
            //2、准备数据
            byte[] data = "我爱你".getBytes();
            //3、打包(发送的地点和端口)
            DatagramPacket packet = new DatagramPacket(data,data.length,InetAddress.getByName("localhost"),8888);
            //4、发送
            client.send(packet);
            //5、释放
            client.close();
    

    5、Socket编程

    基于tcp: 面向连接 安全 可靠 效率低 ,类似于打电话

    Socket编程示意图

    服务器:ServerSocket类

            //1、创建服务器 指定端口
            ServerSocket server = new ServerSocket(8888);
            //2、接收客户端连接 阻塞式
            Socket socket = server.accept();
            System.out.println("一个客户端建立连接");
            //3、发送数据
            String msg = "欢迎使用";
    //        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
    //        bw.write(msg);
    //        bw.newLine();//加行结束符
    //        bw.flush();
    
            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
            dos.writeUTF(msg);
            dos.flush();
    

    客户端:Socket类

     //1、创建客户端 必须指定服务器端和端口
            Socket client = new Socket("localhost",8888);
            //2、接收数据
    //        BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
    //        System.out.println(br.readLine());//阻塞式方法,逐行读取,需要读取的数据有行结束符
    
            DataInputStream dis = new DataInputStream(client.getInputStream());
            System.out.println(dis.readUTF());
    

    6、聊天室的设计

    聊天室版本

    在这里我写了四个聊天室的版本,是循序渐进的,不断完善的。详见源代码。
    版本1:
    客户端可以发送和接收数据,但是只能实现单线程,就是只能实现一个用户发送后再接收。
    版本2:
    客户端新增发送和接收线程,两者独立工作,用户可以实现发生和接收的分离。但是服务器端仍然只能接收一个用户。
    版本3:
    改造服务器,为服务器添加用户容器,可同时添加多个用户及响应多个用户的数据发送和接收。
    版本4:
    新增私聊功能。

    相关文章

      网友评论

          本文标题:【Java基础】java网络编程

          本文链接:https://www.haomeiwen.com/subject/dwufzftx.html