自学内容网 自学内容网

网络编程学习

1、什么是网络编程

在网络通信协议下,不同计算机上运行的程序,进行的数据传输。

  • 应用场景:即时通信、网游对战、金融证券、邮件等等。不管什么场景,都是计算机跟计算机之间通过网络进行数据传输
  • Java中可以使用java.net包下的技术轻松开发出常见的网络应用程序。

2、常见的软件架构

C/S(Client/Server)客户端/服务器:在用户本地需要下载并安装客户端程序,在远程有一个服务器端程序。

B/S(Browser/Server)浏览器/服务器:只需要一个浏览器,用户通过不同的网址,访问不同的服务器。

CS架构和BS架构的区别和优缺点如下:

  • CS架构建立在局域网上,处理面向在相同区域的比较固定的用户群,满足对安全要求高的需求,交互性强,但信息流单一。BS架构建立在广域网上,处理面向分散的地域的不同的用户群,交互能力有限,但可处理如B-B、B-C、B-G等信息,并具有流向的变化。
  • CS架构的优点是本地响应速度快,缺点是二次开发较多时兼容性不好。BS架构的优点是部署简单,缺点是用户感觉反应慢。
  • CS架构适用于局域网中,对硬件的要求高,但开发维护成本高;BS架构适用于广域网中,可以实现跨平台,客户端零维护。
  • C/S结构面向相对固定的用户群,对信息安全的控制能力很强;B/S结构面向不可知的用户群,对安全的控制能力相对弱。

3、网络编程的三要素

 IP、端口号、协议

4、IP及常见的IP分类

IP(Internet Protocol ):是互联网协议地址,也称IP地址,是分配给上网设备的数字标签。设备在网络中的地址,是唯一的标识。最多只有2^32次方个IP,目前已经用完。

4.1 IPv4

IPv4(Internet Protocol version 4),互联网通信协议第四版。采用32位地址长度,分成四组。

32bit(4字节):

11000000 10101000 00000001 01000010-->(点分十进制表示法)192.168.1.66

特殊的IP:127.0.0.1,也可以是localhost,是回送地址也称本地回环地址,也称本机IP,永远只会寻找当前所在本机。

常见的两个CMD命令:

  • ipconfig:查看本机IP地址
  • ping:检查网络是否连通

IPv4的地址分类形式:公网地址(万维网使用)和私有地址(局域网使用)

192.168.开头的就是私有地址,范围即为192.168.0.0 - 192.168.255.255,专门为组织机构内部使用,以此节省IP。

现在如何解决IPv4不够的问题?

  • 采用无类别编址CIDR,使IP地址的分配更加合理
  • 采用网络地址转换(NAT)方法以节省全球IP地址
  • 采用具有更大地址空间的新版本的IPv6

4.2 IPv6

IPv6(Internet Protocol version 6),互联网通信协议第六版。采用128位地址长度,分成8组。大概有2^128个,为了解决IPv4不够用而出现的。

00100000 00000001 00001101 10111000 00000000 00000000 00000000 00100011

00000000 00001000 00001000 00000000 00100000 00001100 01000001 01111010

 

冒分十六进制表示法:2001:0DB8:0000:0023:0008:0800:200C:417A

省略前面的0:2001:DB8:0:23:8:800:200C:417A

 

特殊情况:如果计算出的16进制表示形式中间有多个连续的0,采用0位压缩表示法

FF01:0:0:0:0:0:01101  -->  FF01::1101


public class MyInetAddressDemo1 {
    public static void main(String[] args) throws UnknownHostException {
/*
        static InetAddress getByName(String host)  确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址
        String getHostName()                        获取此IP地址的主机名
        String getHostAddress()                     返回文本显示中的IP地址字符串
*/

      //1.获取InetAddress的对象
        //IP的对象 一台电脑的对象
        InetAddress address = InetAddress.getByName("DESKTOP-5OJJSAM");
        System.out.println(address);

        String name = address.getHostName();//如果获取不到,或者没有这台电脑,以IP的形式返回
        System.out.println(name);//DESKTOP-5OJJSAM

        String ip = address.getHostAddress();
        System.out.println(ip);//192.168.1.100
    }
}

 

5、端口号

端口号:应用程序在设备中唯一的标识。由两个字节表示的整数,取值范围:0~65535。其中0~1023之间的端口号用于一些知名的网络服务或者应用。我们自己使用1024以上的端口号就可以了。

注意:一个端口号只能被一个应用程序使用。

 

6、协议

协议:数据在网络中传输的规则,常见的协议有UDP、TCP、http、https、ftp。

计算机网络中,连接和通信的规则被称为网络通信协议

OSI参考模型:世界互联协议标准,全球通信规范,单模型过于理想化,未能在因特网上进行广泛推广。

TCP/IP参考模型(或TCP/IP协议):事实上的国际标准。

  • 应用层用到了:HTTP、FTP、Telnet、DNS...
  • 传输层用到了:TCP、UDP、...
  • 网络层用到了:IP、ICMP、ARP...
  • 物理+数据链路层:硬件设备 ,最终转成二进制用物理设备进行传输

6.1 UDP协议

UDP协议:用户数据报协议(User Datagram Protocol)

  • UDP是面向无连接通信协议。
  • 速度快,有大小限制,一次最多发送64KB,数据不安全,已丢失数据。

注意:不管两台设备之间的网络是否已经连接成功,数据直接发送,收到收不到拉到。

UDP通信发送数据:

  1. 创建DatagramSocket对象
  2. 打包数据
  3. 发送数据
  4. 释放资源
public class SendMessageDemo {
    public static void main(String[] args) throws IOException {
        //发送数据
        
        //1.创建DatagramSocket对象(快递公司)
        //细节:
        //绑定端口,以后我们就是通过这个端口往外发送
        //空参:所有可用的端口中随机一个进行使用
        //有参:指定端口号进行绑定
        DatagramSocket ds = new DatagramSocket();

        //2.打包数据
        String str = "你好威啊!!!";
        byte[] bytes = str.getBytes();
        InetAddress address = InetAddress.getByName("127.0.0.1");
        int port = 10086;

        DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);

        //3.发送数据
        ds.send(dp);
        
        //4.释放资源
        ds.close();
    }
}

UDP通信接收数据:

  1. 创建DatagramSocket对象
  2. 接收数据包
  3. 解析数据包
  4. 释放资源
public class ReceiveMessageDemo {
    public static void main(String[] args) throws IOException {
        //接收数据
        
        //1.创建DatagramSocket对象(快递公司)
        //细节:
        //在接收的时候,一定要绑定端口
        //而且绑定的端口一定要跟发送的端口保持一致
        DatagramSocket ds = new DatagramSocket(10086);
        
        //2.接收数据包
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes,bytes.length);
        
        //该方法是阻塞的
        //程序执行到这一步的时候,会在这里死等
        //等发送端发送消息
        System.out.println(11111);
        ds.receive(dp);
        System.out.println(2222);
        
        //3.解析数据包
        byte[] data = dp.getData();
        int len = dp.getLength();//获取多少的字节数据
        InetAddress address = dp.getAddress();//获取从哪个电脑发来的
        int port = dp.getPort();

        System.out.println("接收到数据" + new String(data,0,len));//data数组中从0索引开始,len个字节变成字符串
        System.out.println("该数据是从" + address + "这台电脑中的" + port + "这个端口发出的");

        //4.释放资源
        ds.close();
    }
}

练习:聊天室

public class SendMessageDemo {
    public static void main(String[] args) throws IOException {
         /*
            按照下面的要求实现程序
                UDP发送数据:数据来自于键盘录入,直到输入的数据是886,发送数据结束
                UDP接收数据:因为接收端不知道发送端什么时候停止发送,故采用死循环接收
        */

        //1.创建对象DatagramSocket的对象
        DatagramSocket ds = new DatagramSocket();

        //2.打包数据
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请输入您要说的话:");
            String str = sc.nextLine();
            if("886".equals(str)){
                break;
            }
            byte[] bytes = str.getBytes();
            InetAddress address = InetAddress.getByName("255.255.255.255");
            int port = 10086;
            DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);
            //3.发送数据
            ds.send(dp);
        }

        //4.释放资源
        ds.close();
    }
}
public class ReceiveMessageDemo {
    public static void main(String[] args) throws IOException {
        /*
            按照下面的要求实现程序
                UDP发送数据:数据来自于键盘录入,直到输入的数据是886,发送数据结束
                UDP接收数据:因为接收端不知道发送端什么时候停止发送,故采用死循环接收
        */

        //1.创建对象DatagramSocket的对象
        DatagramSocket ds = new DatagramSocket(10086);

        //2.接收数据包
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes,bytes.length);

        while (true) {
            ds.receive(dp);

            //3.解析数据包
            byte[] data = dp.getData();
            int len = dp.getLength();
            String ip = dp.getAddress().getHostAddress();
            String name = dp.getAddress().getHostName();

            //4.打印数据
            System.out.println("ip为:" + ip + ",主机名为:" + name + "的人,发送了数据:" + new String(data,0,len));
        }
    }
}

UDP三种通信方式:

1. 单播

2. 组播

        组播地址:224.0.0.0~239.255.255.255

        其中224.0.0.0~224.0.0.255为预留的组播地址,我们自己用。

3. 广播

        广播地址:255.255.255.255

组播练习:

public class SendMessageDemo {
    public static void main(String[] args) throws IOException {
         /*
            组播发送端代码
        */

        //创建MulticastSocket对象
        MulticastSocket ms = new MulticastSocket() ;

        // 创建DatagramPacket对象
        String s = "你好,你好!" ;
        byte[] bytes = s.getBytes();
        InetAddress address = InetAddress.getByName("224.0.0.1");
        int port = 10000;

        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, address, port) ;

        // 调用MulticastSocket发送数据方法发送数据
        ms.send(datagramPacket);

        // 释放资源
        ms.close();


    }
}
public class ReceiveMessageDemo1 {
    public static void main(String[] args) throws IOException {
        /*
            组播接收端代码
        */


        //1. 创建MulticastSocket对象
        MulticastSocket ms = new MulticastSocket(10000);

        //2. 将将当前本机,添加到224.0.0.1的这一组当中
        InetAddress address = InetAddress.getByName("224.0.0.1");
        ms.joinGroup(address);

        //3. 创建DatagramPacket数据包对象
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length);

        //4. 接收数据
        ms.receive(dp);

        //5. 解析数据
        byte[] data = dp.getData();
        int len = dp.getLength();
        String ip = dp.getAddress().getHostAddress();
        String name = dp.getAddress().getHostName();

        System.out.println("ip为:" + ip + ",主机名为:" + name + "的人,发送了数据:" + new String(data,0,len));

        //6. 释放资源
        ms.close();


    }
}

 

public class ReceiveMessageDemo2 {
    public static void main(String[] args) throws IOException {
        /*
            组播接收端代码
        */


        //1. 创建MulticastSocket对象
        MulticastSocket ms = new MulticastSocket(10000);

        //2. 将将当前本机,添加到224.0.0.1的这一组当中
        InetAddress address = InetAddress.getByName("224.0.0.1");
        ms.joinGroup(address);

        //3. 创建DatagramPacket数据包对象
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length);

        //4. 接收数据
        ms.receive(dp);

        //5. 解析数据
        byte[] data = dp.getData();
        int len = dp.getLength();
        String ip = dp.getAddress().getHostAddress();
        String name = dp.getAddress().getHostName();

        System.out.println("ip为:" + ip + ",主机名为:" + name + "的人,发送了数据:" + new String(data,0,len));

        //6. 释放资源
        ms.close();


    }
}
public class ReceiveMessageDemo3 {
    public static void main(String[] args) throws IOException {
        /*
            组播接收端代码
        */


        //1. 创建MulticastSocket对象
        MulticastSocket ms = new MulticastSocket(10000);

        //2. 将将当前本机,添加到224.0.0.2的这一组当中
        InetAddress address = InetAddress.getByName("224.0.0.2");
        ms.joinGroup(address);

        //3. 创建DatagramPacket数据包对象
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length);

        //4. 接收数据
        ms.receive(dp);

        //5. 解析数据
        byte[] data = dp.getData();
        int len = dp.getLength();
        String ip = dp.getAddress().getHostAddress();
        String name = dp.getAddress().getHostName();

        System.out.println("ip为:" + ip + ",主机名为:" + name + "的人,发送了数据:" + new String(data,0,len));

        //6. 释放资源
        ms.close();


    }
}

6.2 TCP协议

TCP协议:传输控制协议(Transmission Control Protocol)

  • TCP协议是面向连接的通信协议。
  • 速度慢。没有大小限制,数据安全。

注意:确保连接成功,才会发送数据。

TCP通信程序:

TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象,通信之前要确保连接已经建立,通过Socket产生的IO流来进行网络通信。

TCP通信发送数据:

  1. 创建Socket对象
  2. 获取输出流写出数据
  3. 释放资源
public class Client {
    public static void main(String[] args) throws IOException {
        //TCP协议,发送数据

        //1.创建Socket对象
        //细节:在创建对象的同时会连接服务端
        //      如果连接不上,代码会报错
        Socket socket = new Socket("127.0.0.1",10000);


        //2.可以从连接通道中获取输出流
        OutputStream os = socket.getOutputStream();
        //写出数据
        os.write("你好你好".getBytes());//12字节

        //3.释放资源
        os.close();
        socket.close();//四次挥手协议:利用这个协议断开连接
                       //而且保证连接通道里面的数据已经处理完毕了


    }
}

TCP通信接收数据:

  1. 创建ServerSocket对象
  2. 监听客户端连接
  3. 获取输入流读取数据
  4. 释放资源
public class Server {
    public static void main(String[] args) throws IOException {
        //TCP协议,接收数据

        //1.创建对象ServerSocker
        ServerSocket ss = new ServerSocket(10000);

        //2.监听客户端的连接
        Socket socket = ss.accept();//等待客户端连接,如果没有客户端,服务端会一直等待

        //3.从连接通道中获取输入流读取数据
        InputStream is = socket.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);

       // BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        int b;
        while ((b = br.read()) != -1){
            System.out.print((char) b);
        }

        //4.释放资源
        socket.close();
        ss.close();

    }
}

 7、三次握手

三次握手协议:确保连接建立

  1. 客户端向服务器发出连接请求,等待服务器确认
  2. 服务器向客户端返回一个响应,告诉客户端收到了请求
  3. 客户端向服务器再次发出确认信息,连接建立

8、四次挥手

四次挥手协议:确保连接断开,且数据处理完毕

  • 客户端向服务器发出取消连接请求
  • 服务器向客户端返回一个响应,表示已经收到客户端取消请求
  • (服务器将最后的数据处理完毕)
  • 服务器向客户端发出确认取消信息
  • 客户端再次发送确认信息,连接取消

 

 

 

 

 

 

 

 

 

 


原文地址:https://blog.csdn.net/qq_58158407/article/details/142893208

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!