JAVA网络编程

网络编程


只要有你在,我便我所不能

一、简介

二、IP和端口号

1. IP

IP用JAVA中的InetAddress类来表示

  • 1)如何实例化:InetAddress inet = InetAddress.getByName("www.baidu.com");
    • 获取本机IP:InetAddress inet2 = InetAddress.getLocalHost();
  • 2)常用方法:
    • 获取IP:getHostAddress()
    • 获取域名:getHostName()

2. 端口号

① 简介

  • 不同进程有不同端口号
  • 16位整数:0-65535
  • JAVA中使用InetSocketAddress类来表示:
    • InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 8080);

② 分类

  • 公认端口:0~1023
  • 注册端口:1024~49151
  • 动态/私有端口:49152~65535

③ 套接字

  • 端口号与IP地址组合得出一个网络套接字:Socket

④ cmd命令

  • 查看所有端口:netstat -ano
  • 查看指定端口:netstat -aon|findstr “port”
  • 查看具体的进程:tasklist|findstr “port”

⑤ 常用方法

  • 获取IP:getAddress()
  • 获取域名:getHostAddress()
  • 获取端口:getPort()

3. URL

  • 1)URL(同一资源定位器)组成:https://www.google.com:80/index.html
    • 协议
    • 存放资源的主机域名
    • 端口号
    • 资源文件名
  • 2)定义
    • URL url = new URL("https://www.baidu.com:80/index.html?username=zm&age=18#a");
  • 3)常用方法
    • 协议:getProtocol()
    • 域名|ip:getHost()
    • 端口:getPort()
    • 请求资源1:getFile():/index.html?username=zm&age=18
    • 请求资源2:getPath():/index.html
    • 参数:getQuery()
    • 锚点:getRef()

三、网络协议

传输层的两个协议TCP、UDP协议

1. TCP

  • 先建立连接
  • 传输前,采用“三次握手”方式,点对点通信,可靠
  • TCP通信的两个进程:客户端、服务端
  • 可进行大数据量的传输
  • 传输完毕,需要释放连接,效率低

2. UDP

  • 将数据、源、目的封装成数据包,不需要建立连接
  • 每个数据报大小限制在64K
  • 不可靠
  • 可以广播发送
  • 发送数据时无需释放资源, 开销小,速度快

四、TCP网络编程

1. 步骤

① 服务端

  • 1)指定端口,使用ServerSocket创建服务器
  • 2)阻塞式等待连接,accept()
  • 3)操作输入输出流读取数据
  • 4)关闭资源

② 客户端

  • 1)建立连接:创建Socket客户端 + 服务端地址和端口
  • 2)操作输入输出流
  • 3)释放资源

2. 实现

/**
 * 实现TCP网络编程
 *
 * 案例1.客户端发送信息给服务端,服务端将数据显示在控制台
 */
public class Test01TCP {


    //客户端
    @Test
    public void client() {
        //1.创建Socket对象,指明服务器端的ip和端口号
        Socket socket = null;
        OutputStream os = null;
        try {
            InetAddress inet = InetAddress.getByName("localhost");
            socket = new Socket(inet, 8899);

            //2.获取输出流,用于输出数据
            os = socket.getOutputStream();

            //3.写出数据
            os.write("你好,我是客户端mm".getBytes());


        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //4.资源关闭
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    //服务端
    @Test
    public void server(){
        ServerSocket ss = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
            //1.创建服务器端的ServerSocket,指明自己的端口号
            ss = new ServerSocket(8899);

            //2.调用accept()方法,接受客户端的socket
            socket = ss.accept();

            //3.获取输入流
            is = socket.getInputStream();

            //这样写中文数据可能会有乱码
//            byte[] buffer = new byte[20];
//            int len;
//            while ((len = is.read(buffer)) != -1) {
//                String temp = new String(buffer, 0, len);
//                System.out.println(temp);
//            }
//
            //4.读取数据
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[20];
            int len;
            while ((len = is.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }

            System.out.println(baos.toString());

            System.out.println("收到了来自于:" + socket.getInetAddress().getHostAddress() + "的数据");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //5.关闭资源
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (ss != null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3. 案例

更多案例去看project/java/java se/idea/javaSE01 中的代码

五、UDP网络编程

1. 简介

  • DatagramSocket:用于发送或接收数据包的套接字
  • DatagramPacket:数据包

2. 实现

① 客户端

@Test
public void client() throws Exception {
    /*
         * 1.使用DatagramSocket 指定端口,创建接收端
         * 2.准备数据,转成字节数组
         * 3.封装成DatagramPacket包裹,指明目的地
         * 4.发送包裹send(DatagramPacket)
         * 5.释放资源
         * */

    System.out.println("客户端启动...");

    //1.使用DatagramSocket 指定端口,创建接收端
    DatagramSocket client = new DatagramSocket(8888);

    //2.准备数据,转成字节数组
    String data = "你好,我是客户端";
    byte[] datas = data.getBytes();

    // 3.封装成DatagramPacket包裹,指明目的地
    DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("localhost", 9999));

    //4.发送包裹send(DatagramPacket)
    client.send(packet);

    //5.释放资源
    client.close();

}

② 服务端

 @Test
public void sever() throws Exception {
    /*
        * 1.使用DatagramSocket 指定端口,创建接收端
        * 2.准备容器,封装成DatagramPacket包裹
        * 3.阻塞式接收receive(DatagramPacket)
        * 4.分析数据
        *       getData()
        *       getLength()
        * 5.释放资源
        * */

    System.out.println("服务器启动中...");
    //1.使用DatagramSocket 指定端口,创建接收端
    DatagramSocket server = new DatagramSocket(9999);

    //2.准备容器,封装成DatagramPacket包裹
    byte[] container = new byte[1024*60];
    DatagramPacket packet = new DatagramPacket(container, 0, container.length);

    //3.阻塞式接收receive(DatagramPacket)
    server.receive(packet);

    //4.分析数据
    byte[] datas = packet.getData();
    int len = packet.getLength();
    System.out.println(new String(datas, 0, len));

    //5.释放资源
    server.close();
}

3. 简易对话

添加了多线程、和面向对象封装

① 封装发送端

/**
 * UDP编程
 *
 * 面向对象封装:发送端
 */
public class Test03_Send implements Runnable{
    private DatagramSocket client;
    private BufferedReader reader;
    private String toIP;
    private int toPort;

    //构造器,初始化IP、端口信息
    public Test03_Send(int port, String toIP, int toPort) {
        this.toIP = toIP;
        this.toPort = toPort;
        try {
            client = new DatagramSocket(port);
            reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "启动...");
        while (true) {
            String data = null;
            try {
                data = reader.readLine();
                byte[] datas = data.getBytes();

                //3.打包数据
                DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(this.toIP, this.toPort));

                //4.发送包
                client.send(packet);

                if ("bye".equals(data)){
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //5.释放资源
        client.close();
    }
}

② 封装接收端

/**
 * UDP编程
 *
 * 面向对象封装:接收端
 */
public class Test03_Receive implements Runnable {
    private DatagramSocket server;
    private String from;

    //构造器,初始化端口
    public Test03_Receive(int port, String from) {
        this.from = from;
        try {
            server = new DatagramSocket(port);

        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "启动...");
        while (true) {
            //2.准备容器,接收数据,准备包裹,包裹数据
            byte[] container = new byte[1024*60];
            DatagramPacket packet = new DatagramPacket(container, 0, container.length);
            try {
                //3.阻塞式接收数据
                server.receive(packet);
                //4.处理数据
                byte[] datas = packet.getData();
                int len = packet.getLength();
                String data = new String(datas, 0, len);
                System.out.println(from + ":" + data);

                if ("bye".equals(data)){
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //5.关闭资源
        server.close();
    }
}

③ 学生

/**
 * 加入多线程:实现双向交流
 * 学生端
 * 接收端口:7777
 * 发送端口:8888
 */
public class Test03_Student {
    public static void main(String[] args) {
        //发送
        Thread student_send = new Thread(new Test03_Send(8888, "localhost", 9999));
        student_send.start();


        //接收
        Thread student_receive = new Thread(new Test03_Receive(7777, "老师"));
        student_receive.start();
    }
}

④ 老师

/**
 * 加入多线程:实现双向交流
 * 老师端
 * 接收端口:9999
 * 发送端口:6666
 */
public class Test03_Teacher {
    public static void main(String[] args) {
        //接收
        Thread teacher_receive = new Thread(new Test03_Receive(9999, "学生"));
        teacher_receive.start();

        //发送
        Thread teacher_send = new Thread(new Test03_Send(6666, "localhost", 7777));
        teacher_send.start();
    }
}

更多案例去看project/java/java se/idea/javaSE01 中的代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值