Java 网络基础知识

目录

什么是网络编程

常见的软件架构

网络编程三要素

IP

端口

协议

Java实现网络通信

InetAddress类:

UDP协议发送数据:

UDP协议接收数据:

TCP通信协议接收和发送消息

TCP协议三次握手和四次挥手

三次握手

四次挥手


什么是网络编程

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

例如:即时通信、邮件、网络游戏等等。

常见的软件架构

C/S:Client/Server(客户端/服务器)

需要用户在本地下载并安装客户端程序,在远程有一个服务器端程序。例如QQ、WeGame。

B/S:Browser/Server(浏览器/服务器)

只需要一个浏览器,用户输入不同的网址,就可以访问不同的服务器。例如淘宝,京东。

C/S优缺点:

优点:

        用户体验好

缺点:

        用户需要下载或者更新客户端

        需要同时开发客户端和服务器

B/S优缺点:

优点:不需要开发客户端,只需要开发页面+服务端

           用户不需要下载客户端,打开浏览就能用(所有的数据,都由服务端传给浏览器)

缺点:如果应用过大,用户体验差。

总结:对于画面和音乐有高的要求用C/S架构

           对于画质没啥要求,显示就行采用B/S架构

网络编程三要素

IP(网络中的设备地址,唯一标识)、端口号(设备中程序的唯一标识,由2个字节表示的整数)、协议(数据在网络中传输的规则,UDP、TCP、HTTP、HTTPS、FTP等)。

IP

IPv4:采用32位地址长度,分成4组。即32个bit4个字节(一个字节有8位2进制数,1字节=8比特)。

点分十进制:192.168.1.20

2019年256^4全部分配完毕,出现了IPv6。

IPv6:采用128位地址长度,分成8组。即128bit16个字节。

冒分十六进制+0位压缩表示法(::中间会补0,补齐16位):fe80::4ddd:1da2:417e:ab44%9。

%:IPv6地址中的某些地址范围(如链接本地地址和唯一本地地址)不仅依赖于主机的地址,还依赖于网络接口(例如,网络适配器或网卡)。使用百分号标识符是为了确保正确选择要使用的网络接口。不同的网络接口可以有不同的地址,因此需要在地址后面使用%来明确指定应该使用哪个接口。

目前如何解决IP不够的问题?使用局域网。

IPv4的地址分类:

公网地址(万维网使用)和私有地址(局域网使用)。

192.168.开头的就是私有地址,为组织机构内部使用,可以来节省IP。例如网吧:每台计算机IP都是192.168开头,多台计算机有一个共同的公网IP。

端口

由2个字节组成,设备上应用程序的标识。

协议

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

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

OSI参考模型TCP/IP参考模型TCP/IP模型各层对应协议面向哪些方向
应用层应用层HTTP、FTP、Telnet、DNS...应用程序需要关注的,程序员一般在这一层开发,如浏览器、邮箱。
表示层
会话层
传输层传输层TCP、UDP...选择传输使用的TCP、UDP协议
网络层网络层IP、ICMP、ARP...封装自己的IP,对方的IP等信息
数据链路层物理+数据链路层硬件设备转换成二进制利用物理设备传输
物理层

UDP协议:

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

什么是面向无连接?计算机发消息给另一台时,不会管他们是否连接成功,该协议只负责发消息。

应用:语音聊天、视频会议,丢失数据会卡顿,不影响使用。

TCP协议:

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

面向连接:计算机发送消息时会先确保他们连接成功,再发送消息。

应用:发送消息、邮件。不能丢数据,会改变消息意思。

Java实现网络通信

InetAddress类:

创建对象:通过静态方法getByName()创建对象,他会根据电脑默认使用的ip创建IPv4的实现类(Inet4Address)或者IPv6的实现类(Inet6Address)。

对象方法:getHostName()获取主机名称,getHostAddress():获取主机IP地址。

UDP协议发送数据:

/**
 * UDP发送信息
 */
@Test
public void test1() throws Exception{
    // 数据包发送 ,空参会在可用端口中选一个使用
    DatagramSocket datagramSocket = new DatagramSocket();
    String data = "hello word!";
    byte[] bytes = data.getBytes();
    InetAddress ip = InetAddress.getByName("127.0.0.1");
    int port = 5200;
    // 数据包打包封装
    DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length,ip,port);
    datagramSocket.send(datagramPacket);
    datagramSocket.close();
}

UDP协议接收数据:

/**
 * UDP接收信息
 */
@Test
public void test2() throws Exception {
    // 接收数据参数要与发送数据的端口保持一致
    DatagramSocket datagramSocket = new DatagramSocket(5200);
    byte[] bytes = new byte[1024];
    DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length);
    datagramSocket.receive(datagramPacket);
    InetAddress ip = datagramPacket.getAddress();
    int port = datagramPacket.getPort();
    byte[] data = datagramPacket.getData();
    // 该方法是阻塞的
    datagramSocket.close();
    System.out.println(ip.getHostAddress()+":"+port+new String(data));
}

 聊天室案例

/**
 * UDP发送信息:人员1
 */
@Test
public void test3() throws Exception{
    // 数据包发送,空参会在可用端口中选一个使用
    DatagramSocket datagramSocket = new DatagramSocket();
    Scanner scanner = new Scanner(System.in);
    while (true) {
        System.out.println("请输入内容:");
        String str = scanner.nextLine();
        if("#".equals(str)){
            break;
        }
        byte[] bytes = str.getBytes();
        InetAddress ip = InetAddress.getByName("127.0.0.1");
        int port = 5200;
        DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length,ip,port);
        datagramSocket.send(datagramPacket);
    }
    datagramSocket.close();
}
 /**
 * UDP发送信息:人员2
 */
@Test
public void test4() throws Exception{
    // 数据包发送,空参会在可用端口中选一个使用
    DatagramSocket datagramSocket = new DatagramSocket();
    Scanner scanner = new Scanner(System.in);
    while (true) {
        System.out.println("请输入内容:");
        String str = scanner.nextLine();
        if("#".equals(str)){
            break;
        }
        byte[] bytes = str.getBytes();
        InetAddress ip = InetAddress.getByName("127.0.0.1");
        int port = 5200;
        DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length,ip,port);
        datagramSocket.send(datagramPacket);
    }
    datagramSocket.close();
}
 /**
 * UDP接收信息:聊天室
 */
@Test
public void test5() throws Exception {
    DatagramSocket datagramSocket = new DatagramSocket(5200);
    byte[] bytes = new byte[1024];
    DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length);
    while (true) {
        datagramSocket.receive(datagramPacket);
        InetAddress ip = datagramPacket.getAddress();
        int port = datagramPacket.getPort();
        byte[] data = datagramPacket.getData();
        System.out.println(ip.getHostAddress()+":"+port+new String(data));
    }
}

注意:在Spring Boot测试中,特别是在运行单元测试时,控制台输入通常会受到限制,导致无法直接输入内容并被Scanner读取。这是因为测试运行是自动化的,通常在没有实际交互性控制台的情况下运行,因此不支持直接从控制台输入。

UDP三种通信方式

单播:单对单发送信息

组播:单对局域网中一组发信息

组播地址:224.0.0.0~239.255.255.255其中224.0.0.0~224.0.0.255为预留的组播地址

MulticastSocket类代替DatagramSocket,在接收端时调用joinGroup方法放入一组。

广播:单对局域网中所有设备发送信息

广播地址:255.255.255.255

发送端将DatagramSocket的Ip改为255.255.255.255就是广播。

TCP通信协议接收和发送消息

/**
 * TCP发送消息
 */
@Test
public void test6() throws Exception {
    // 创建对象时会自动创建连接,连接失败会报异常
    // 三次握手保证连接建立
    Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),5200);
    OutputStream outputStream = socket.getOutputStream();
    byte[] bytes = "你好,世界!".getBytes("UTF-8");
    // 往输出流中写数据就会发送消息
    outputStream.write(bytes);
    // 一次消息发送结束标记,不给结束标记,在另一端会一直读取通道信息。
    socket.shutdownOutput();
    outputStream.close();
    // 四次挥手 断开连接并且保证连接通道数据已经被处理完
    socket.close();
}
 /**
 * TCP接收消息
 */
@Test
public void test7() throws Exception {
    ServerSocket serverSocket = new ServerSocket(5200);
    // 阻塞
    Socket accept = serverSocket.accept();
    InputStream inputStream = accept.getInputStream();
    InputStreamReader reader = new InputStreamReader(inputStream);
    BufferedReader bufferedReader = new BufferedReader(reader);
    int b;
    while ((b = bufferedReader.read()) > -1){
        System.out.print((char)b);
    }
    inputStream.close();
}

TCP协议三次握手和四次挥手

三次握手

四次挥手

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值