Java基础(五)

前言:本博客主要记录学习网络通信的基本知识以及网络编程的应用。

网络编程

基本的通信架构

CS架构(Cilent客户端/Server服务端)

BS架构(Browser浏览器/Server服务端)

网络通信三要素

网络通信三要素:IP地址、端口、协议

IP地址

作用:找到网络上的通信设备

  • IPv4
  • IPv6

公网IP

内网IP 192.168.0.0

特殊的IP:127.0.0.1、localhost 代表本机

Ping IP地址,查看网络是否连通

InetAddress

package learn14;

import java.net.InetAddress;

public class InetAddressTest {
    public static void main(String[] args) throws Exception {
        //获取本机IP地址对象
        InetAddress ip1 = InetAddress.getLocalHost();
        System.out.println(ip1.getHostName());
        System.out.println(ip1.getHostAddress());
        //获取指定IP或域名的IP地址对象
        InetAddress ip2 = InetAddress.getByName("www.baidu.com");
        System.out.println(ip2.getHostName());
        System.out.println(ip2.getHostAddress());

        System.out.println(ip2.isReachable(10000));
    }
}

Java基础(五)_第1张图片

端口

作用:找到设备中的应用程序

范围是0~65535

分类:

周知端口:0~1023,预先定义的知名应用占用(HTTP 80 FTP 81)

注册端口:1024~49151,分配给进程或某些应用程序

动态端口:49152~65535,不固定分配给某种进程

自己开发的程序一般选择使用注册端口,且一个设备中不能出现两个程序的端口号一样,否则出错

协议

网络上通信的设备,事先规定的连接规则,以及传输数据的规则,被称为网络通信协议

OSI网络参考模型

TCP/IP网络模型

传输层的2个通信协议

UDP 用户数据报协议

特点:无连接、不可靠协议

应用:通信效率高,适合语音通话、视频直播

TCP 通信协议

特点:面向连接、可靠协议

TCP主要有三个步骤实现可靠连接:三次握手建立连接,传输数据进行确认,四次握手断开连接。

应用:通信效率相对不高,适合网页、文件下载、支付

TCP 传输控制协议

网络编程

UDP通信

客户端发送数据,服务端接受数据

一次发送,一次接收

package learn14;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class Client {
    public static void main(String[] args) throws Exception {
        //创建客户端对象 (发数据)
        DatagramSocket socket = new DatagramSocket(8888);
        //创建数据包对象封装要发出去的数据
        byte[] bytes = "hello,world".getBytes();
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 6666);
        socket.send(packet);
        System.out.println("客户端数据发送完毕!");

        socket.close();

    }
}
package learn14;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动!");
        //创建一个服务端对象
        DatagramSocket socket = new DatagramSocket(6666);
        //创建一个数据包对象
        byte[] buffer = new byte[1024 * 64];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
        //使用数据包来接受客户端发来的数据
        socket.receive(packet);
        //获取本次数据包接收的数据 接受多少打印出来
        int len = packet.getLength();
        String rs = new String(buffer, 0, len);
        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(packet.getPort());
        System.out.println(rs);
    }
}

多次发送,多次接收

package learn14;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动!");
        //创建一个服务端对象
        DatagramSocket socket = new DatagramSocket(6666);
        //创建一个数据包对象
        byte[] buffer = new byte[1024 * 64];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
        //使用数据包来接受客户端发来的数据
        while (true) {
            socket.receive(packet);
            //获取本次数据包接收的数据 接受多少打印出来
            int len = packet.getLength();
            String rs = new String(buffer, 0, len);
            System.out.println(rs);
            System.out.println(packet.getAddress().getHostAddress());
            System.out.println(packet.getPort());
        }
    }
}
package learn14;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) throws Exception {
        //创建客户端对象 (发数据)
        DatagramSocket socket = new DatagramSocket();
        //创建数据包对象封装要发出去的数据
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请说:");
            String msg = sc.nextLine();
            if ("exit".equals(msg)) {
                System.out.println("欢迎下次光临");
                socket.close();
                break;
            }
            byte[] bytes = msg.getBytes();
            DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 6666);
            socket.send(packet);
        }

    }
}

需要配置下,多开几个客户端

Java基础(五)_第2张图片

需要注意,端口号需要随机分配,否则会有以下报错

Java基础(五)_第3张图片

TCP通信

一次发送,一次接收

package learn14;

import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;

public class ClientTCP {
    public static void main(String[] args) throws Exception {
        //创建Socket对象
        Socket socket = new Socket("127.0.0.1", 8888);
        //从socket通信管道中得到一个字节输出流,用来发送数据给服务程序
        OutputStream os = socket.getOutputStream();
        //把低级的字节输出流包装成数据输出流
        DataOutputStream dos = new DataOutputStream(os);
        //写入数据
        dos.writeUTF("hello!!!");
        //释放连接资源
        dos.close();
        socket.close();
    }
}
package learn14;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerTCP {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动成功");
        //创建ServerSocket对象
        ServerSocket serverSocket = new ServerSocket(8888);
        //使用ServerSocket对象
        Socket socket = serverSocket.accept();
        //从socket通信管道得到一个字节输入流
        InputStream is = socket.getInputStream();
        //把原始的字节输入流包装成数据输入流
        DataInputStream dis = new DataInputStream(is);
        //使用数据输入流读取客户端发送的消息
        String rs = dis.readUTF();
        System.out.println(rs);

        System.out.println(socket.getRemoteSocketAddress());
        dis.close();
        socket.close();
    }
}

多次发送,多次接收

package learn14;

import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class ClientTCP {
    public static void main(String[] args) throws Exception {
        //创建Socket对象
        Socket socket = new Socket("127.0.0.1", 8888);
        //从socket通信管道中得到一个字节输出流,用来发送数据给服务程序
        OutputStream os = socket.getOutputStream();
        //把低级的字节输出流包装成数据输出流
        DataOutputStream dos = new DataOutputStream(os);
        Scanner sc = new Scanner(System.in);
        //写入数据
        while (true) {
            System.out.println("请说:");
            String msg = sc.nextLine();
            if ("exit".equals(msg)) {
                System.out.println("退出成功,欢迎下次光临!");
                dos.close();
                socket.close();
                break;
            }
            dos.writeUTF(msg);
            dos.flush();
        }
    }
}
package learn14;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerTCP {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动成功");
        //创建ServerSocket对象
        ServerSocket serverSocket = new ServerSocket(8888);
        //使用ServerSocket对象
        Socket socket = serverSocket.accept();
        //从socket通信管道得到一个字节输入流
        InputStream is = socket.getInputStream();
        //把原始的字节输入流包装成数据输入流
        DataInputStream dis = new DataInputStream(is);
        //使用数据输入流读取客户端发送的消息
        while (true) {
            try {
                String rs = dis.readUTF();
                System.out.println(rs);
                System.out.println(socket.getRemoteSocketAddress());
            } catch (IOException e) {
                System.out.println(socket.getRemoteSocketAddress() + "离线了");
                dis.close();
                socket.close();
                break;
            }
        }
    }
}

多个客户端同时通信

package learn14;

import java.io.DataInputStream;
import java.io.InputStream;
import java.net.Socket;

public class ServerReaderThead extends Thread {
    private Socket socket;

    public ServerReaderThead(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            InputStream is = socket.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            while (true) {
                try {
                    String msg = dis.readUTF();
                    System.out.println(msg);
                } catch (Exception e) {
                    System.out.println("有客户端下线了:" + socket.getRemoteSocketAddress());
                    dis.close();
                    socket.close();
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
package learn14;

import java.net.ServerSocket;
import java.net.Socket;

public class ServerTCP {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动成功");
        //创建ServerSocket对象
        ServerSocket serverSocket = new ServerSocket(8888);
        //使用ServerSocket对象
        while (true) {
            Socket socket = serverSocket.accept();
            System.out.println("客户端上线了:"+socket.getRemoteSocketAddress());
            //将通信管道交给独立的线程处理
            new ServerReaderThead(socket).start();
        }
    }
}
package learn14;

import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class ClientTCP {
    public static void main(String[] args) throws Exception {
        //创建Socket对象
        Socket socket = new Socket("127.0.0.1", 8888);
        //从socket通信管道中得到一个字节输出流,用来发送数据给服务程序
        OutputStream os = socket.getOutputStream();
        //把低级的字节输出流包装成数据输出流
        DataOutputStream dos = new DataOutputStream(os);
        Scanner sc = new Scanner(System.in);
        //写入数据
        while (true) {
            System.out.println("请说:");
            String msg = sc.nextLine();
            if ("exit".equals(msg)) {
                System.out.println("退出成功,欢迎下次光临!");
                dos.close();
                socket.close();
                break;
            }
            dos.writeUTF(msg);
            dos.flush();
        }
    }
}

你可能感兴趣的:(测试技术,Java,网络编程,网络通信)