java-网络编程-UDP,TCP通信

基本通信架构

  • CS架构(Client客户端/Server服务端)
  • BS架构(Browser浏览器/Server服务端)

网络通信三要素

IP地址

常用命令:

ipconfig:查看本机IP地址

ping IP地址:检查网络是否连通

InetAddress

代表IP地址
常用方法

java 复制代码
public class InetAddressDemo1 {
    public static void main(String[] args) {
        //InetAddress获取本机IP对象和对方IP对象
        try {
            //1、获取本机IP对象
            InetAddress local = InetAddress.getLocalHost();
            System.out.println(local);
            System.out.println(local.getHostName());
            System.out.println(local.getHostAddress());
            //2、获取对方IP对象
            InetAddress remote = InetAddress.getByName("www.mihoyo.com");
            System.out.println(remote.getHostName());
            System.out.println(remote.getHostAddress());
            //3、判断IP地址是否可达
            boolean reachable = remote.isReachable(5000);
            System.out.println(reachable);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

端口

计算机内部标记应用程序的序号,范围0-65535

  • 分类
    周知端口:0-1023,被预定义的知名应用占用
    注册端口:1024-49151,分配给应用程序和用户进程
    动态端口:49152-65535,动态分配

协议

UDP(用户数据报协议):无连接,不可靠

数据按照包发

java提供了java.net.DatagramSocket类实现UDP通信

  • 一发一收
java 复制代码
public class UPDClientDemo1 {
    public static void main(String[] args) throws Exception {
        System.out.println("客户端启动了...");
        //UPD通信一发一收:客户端
        //1、创建发送端对象
        DatagramSocket socket = new DatagramSocket();
        //2、创建数据包对象,封装数据
        byte[] data = "UPD通信一发一收".getBytes();
        /**
         * public DatagramPacket(byte[] buf, int length, InetAddress address, int port)
         * 参数一:数据,字节数组
         * 参数二:数据长度
         * 参数三:指定接收端的IP地址
         * 参数四:指定接收端的端口号
         */
        DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getLocalHost(), 10086);

        //3、发送端对象发送数据包的数据
        socket.send(packet);
    }
}
java 复制代码
public class UPDServerDemo2 {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动了...");
        //UPD通信一发一收:服务端
        //1、创建接收端对象,注册端口
        DatagramSocket socket = new DatagramSocket(10086);

        //2、创建数据包对象,接收数据
        byte[] buf = new byte[1024 * 64];
        DatagramPacket packet = new DatagramPacket(buf, buf.length);

        //3、接收数据
        socket.receive(packet);

        //4、解析数据
        //获取当前接收到的数据长度
        int length = packet.getLength();
        String data = new String(buf, 0, length);
        System.out.println("服务端收到数据:" + data);

        //获取对方IP对象和程序端口
        String ip = packet.getAddress().getHostAddress();
        int port = packet.getPort();
        System.out.println("对方IP:" + ip + ",端口:" + port);

    }
}
  • 多发多收
java 复制代码
public class UPDServerDemo2 {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动了...");
        //UPD通信多发多收:服务端
        //1、创建接收端对象,注册端口
        DatagramSocket socket = new DatagramSocket(10086);

        //2、创建数据包对象,接收数据
        byte[] buf = new byte[1024 * 64];
        DatagramPacket packet = new DatagramPacket(buf, buf.length);

        while (true) {
            //3、接收数据
            socket.receive(packet);//阻塞式接收数据

            //4、解析数据
            //获取当前接收到的数据长度
            int length = packet.getLength();
            String data = new String(buf, 0, length);
            System.out.println("服务端收到数据:" + data);

            //获取对方IP对象和程序端口
            String ip = packet.getAddress().getHostAddress();
            int port = packet.getPort();
            System.out.println("对方IP:" + ip + ",端口:" + port);

            System.out.println("----------------");
        }
    }
}
java 复制代码
public class UPDClientDemo1 {
    public static void main(String[] args) throws Exception {
        System.out.println("客户端启动了...");
        //UPD通信多发多收:客户端
        //1、创建发送端对象
        DatagramSocket socket = new DatagramSocket();
        DatagramPacket packet = null;

        Scanner sc = new Scanner(System.in);

        while (true) {
            System.out.println("请输入要发送的数据:");
            String data = sc.nextLine();

            //若输入exit则退出
            if ("exit".equals(data)) {
                System.out.println("客户端退出了...");
                socket.close();
                break;
            }

            //2、创建数据包对象,封装数据
            byte[] bytes = data.getBytes();
            packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 10086);

            //3、发送端对象发送数据包的数据
            socket.send(packet);
        }
    }
}

TCP(传输控制协议):面向连接,可靠通信

java提供了java.net.Socket类实现TCP通信

  • 一发一收
    客户端
java 复制代码
public class ClientDemo1 {
    public static void main(String[] args) throws Exception {
        //TCP通信下一发一收:客户端
        //1、创建socket管道对象,请求与服务端的socket链接,可靠连接
        Socket socket = new Socket("127.0.0.1", 10086);

        //2、从socket通信管道中得到字节输出流
        OutputStream os = socket.getOutputStream();

        //3、特殊数据流
        DataOutputStream dos = new DataOutputStream(os);
        dos.writeInt(1);
        dos.writeUTF("嗨,想我了吗?");

        //4、关闭管道
        socket.close();
    }
}

服务端

服务端是通过java.net包下的ServerSocket类实现的

java 复制代码
public class ServerDemo2 {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动了...");
        //TCP通信一发一收:服务端
        //1、创建服务端ServerSocket对象,注册端口
        ServerSocket server = new ServerSocket(10086);
        //2、调用accept方法,阻塞等待客户端连接,一旦有客户端连接,返回Socket对象
        Socket socket = server.accept();
        //3、获取输入流,读取数据
        InputStream is = socket.getInputStream();
        //4、把字节输入流包装成特殊数据输入流
        DataInputStream dis = new DataInputStream(is);
        //5、读取数据
        int id = dis.readInt();
        String msg = dis.readUTF();
        System.out.println("id:" + id + ",收到消息:" + msg);
        //6、客户端ip和端口
        System.out.println("客户端IP:" + socket.getInetAddress().getHostAddress());
        System.out.println("客户端端口:" + socket.getPort());
    }
}
  • 多发多收
java 复制代码
public class ClientDemo1 {
    public static void main(String[] args) throws Exception {
        System.out.println("客户端启动了...");
        //TCP通信下多发多收:客户端
        //1、创建socket管道对象,请求与服务端的socket链接,可靠连接
        Socket socket = new Socket("127.0.0.1", 10086);

        //2、从socket通信管道中得到字节输出流
        OutputStream os = socket.getOutputStream();

        //3、特殊数据流
        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("886,程序退出...");
                socket.close();
                break;
            }
            dos.writeUTF(msg);
            dos.flush();
        }
    }
}
java 复制代码
public class ServerDemo2 {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动了...");
        //TCP通信多发多收:服务端
        //1、创建服务端ServerSocket对象,注册端口
        ServerSocket server = new ServerSocket(10086);
        //2、调用accept方法,阻塞等待客户端连接,一旦有客户端连接,返回Socket对象
        Socket socket = server.accept();
        //3、获取输入流,读取数据
        InputStream is = socket.getInputStream();
        //4、把字节输入流包装成特殊数据输入流
        DataInputStream dis = new DataInputStream(is);
        while (true) {
            //5、读取数据
            String msg = dis.readUTF();
            System.out.println("收到消息:" + msg);
            //6、客户端ip和端口
            System.out.println("客户端IP:" + socket.getInetAddress().getHostAddress());
            System.out.println("客户端端口:" + socket.getPort());
            System.out.println("-------------------------");
        }
    }
}

服务端支持多个客户端同时连接

java 复制代码
public class ServerDemo2 {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动了...");
        //TCP通信多发多收:服务端,支持多个客户端连接
        //1、创建服务端ServerSocket对象,注册端口
        ServerSocket server = new ServerSocket(10086);
        while (true) {
            //2、调用accept方法,阻塞等待客户端连接,一旦有客户端连接,返回Socket对象
            Socket socket = server.accept();
            //3、把这个客户端管道交给一个独立的子线程专门负责接收这个管道的消息
            new ServerReader(socket).start();
        }
    }
}
java 复制代码
public class ServerReader extends  Thread{
    private Socket socket;
    public ServerReader(Socket socket) {
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            InputStream is = socket.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            while (true) {
                String msg = dis.readUTF();
                System.out.println("客户端:" + msg);
                //客户端ip和端口
                System.out.println("客户端ip:" + socket.getInetAddress().getHostAddress());
                System.out.println("客户端端口:" + socket.getPort());
            }
        } catch (Exception e) {
            System.out.println("客户端下线了" + socket.getInetAddress().getHostAddress());
        }
    }
}
相关推荐
酉鬼女又兒2 分钟前
零基础入门IPv4地址:从基本概念、分类编址、子网划分到无分类编址与应用规划全解
网络·网络协议·计算机网络·考研·职场和发展·分类·智能路由器
多彩电脑6 分钟前
向AIDE(安卓设备上的Android Studio)导入aar库
android·java·开发语言·androidx
未来侦察班6 分钟前
网络协议 数据链路层,“帧”建立统一新秩序
网络·网络协议
阿维的博客日记15 分钟前
Windows自由切换jdk版本
java·windows
ICT系统集成阿祥18 分钟前
校园网络准入认证建设与运维经验
运维·网络·智慧校园·经验总结
摇滚侠18 分钟前
MyBatis 入门到项目实战 MyBatis 逆向工程 62
java·开发语言·mybatis
ch.ju22 分钟前
Java Programming Chapter 4——Multi-level inheritance
java·开发语言
yuezhilangniao26 分钟前
2026删除K8s命名空间 卡 Terminating 的 ns
java·容器·kubernetes
liulilittle30 分钟前
甲骨文云中国大陆定向 QoS 原理及绕过解决方案
服务器·开发语言·网络·计算机网络·oracle·通信·qos
行走__Wz32 分钟前
【网工入门-eNSP模拟-02】dhcp动态主机配置ip地址
服务器·网络·tcp/ip