• 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

    1. package learn14;
    2. import java.net.InetAddress;
    3. public class InetAddressTest {
    4. public static void main(String[] args) throws Exception {
    5. //获取本机IP地址对象
    6. InetAddress ip1 = InetAddress.getLocalHost();
    7. System.out.println(ip1.getHostName());
    8. System.out.println(ip1.getHostAddress());
    9. //获取指定IP或域名的IP地址对象
    10. InetAddress ip2 = InetAddress.getByName("www.baidu.com");
    11. System.out.println(ip2.getHostName());
    12. System.out.println(ip2.getHostAddress());
    13. System.out.println(ip2.isReachable(10000));
    14. }
    15. }

    端口

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

    范围是0~65535

    分类:

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

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

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

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

    协议

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

    OSI网络参考模型

    TCP/IP网络模型

    传输层的2个通信协议

    UDP 用户数据报协议

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

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

    TCP 通信协议

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

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

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

    TCP 传输控制协议

    网络编程

    UDP通信

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

    一次发送,一次接收

    1. package learn14;
    2. import java.net.DatagramPacket;
    3. import java.net.DatagramSocket;
    4. import java.net.InetAddress;
    5. public class Client {
    6. public static void main(String[] args) throws Exception {
    7. //创建客户端对象 (发数据)
    8. DatagramSocket socket = new DatagramSocket(8888);
    9. //创建数据包对象封装要发出去的数据
    10. byte[] bytes = "hello,world".getBytes();
    11. DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 6666);
    12. socket.send(packet);
    13. System.out.println("客户端数据发送完毕!");
    14. socket.close();
    15. }
    16. }
    1. package learn14;
    2. import java.net.DatagramPacket;
    3. import java.net.DatagramSocket;
    4. public class Server {
    5. public static void main(String[] args) throws Exception {
    6. System.out.println("服务端启动!");
    7. //创建一个服务端对象
    8. DatagramSocket socket = new DatagramSocket(6666);
    9. //创建一个数据包对象
    10. byte[] buffer = new byte[1024 * 64];
    11. DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
    12. //使用数据包来接受客户端发来的数据
    13. socket.receive(packet);
    14. //获取本次数据包接收的数据 接受多少打印出来
    15. int len = packet.getLength();
    16. String rs = new String(buffer, 0, len);
    17. System.out.println(packet.getAddress().getHostAddress());
    18. System.out.println(packet.getPort());
    19. System.out.println(rs);
    20. }
    21. }

    多次发送,多次接收

    1. package learn14;
    2. import java.net.DatagramPacket;
    3. import java.net.DatagramSocket;
    4. public class Server {
    5. public static void main(String[] args) throws Exception {
    6. System.out.println("服务端启动!");
    7. //创建一个服务端对象
    8. DatagramSocket socket = new DatagramSocket(6666);
    9. //创建一个数据包对象
    10. byte[] buffer = new byte[1024 * 64];
    11. DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
    12. //使用数据包来接受客户端发来的数据
    13. while (true) {
    14. socket.receive(packet);
    15. //获取本次数据包接收的数据 接受多少打印出来
    16. int len = packet.getLength();
    17. String rs = new String(buffer, 0, len);
    18. System.out.println(rs);
    19. System.out.println(packet.getAddress().getHostAddress());
    20. System.out.println(packet.getPort());
    21. }
    22. }
    23. }
    1. package learn14;
    2. import java.net.DatagramPacket;
    3. import java.net.DatagramSocket;
    4. import java.net.InetAddress;
    5. import java.util.Scanner;
    6. public class Client {
    7. public static void main(String[] args) throws Exception {
    8. //创建客户端对象 (发数据)
    9. DatagramSocket socket = new DatagramSocket();
    10. //创建数据包对象封装要发出去的数据
    11. Scanner sc = new Scanner(System.in);
    12. while (true) {
    13. System.out.println("请说:");
    14. String msg = sc.nextLine();
    15. if ("exit".equals(msg)) {
    16. System.out.println("欢迎下次光临");
    17. socket.close();
    18. break;
    19. }
    20. byte[] bytes = msg.getBytes();
    21. DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 6666);
    22. socket.send(packet);
    23. }
    24. }
    25. }

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

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

    TCP通信

    一次发送,一次接收

    1. package learn14;
    2. import java.io.DataOutputStream;
    3. import java.io.OutputStream;
    4. import java.net.Socket;
    5. public class ClientTCP {
    6. public static void main(String[] args) throws Exception {
    7. //创建Socket对象
    8. Socket socket = new Socket("127.0.0.1", 8888);
    9. //从socket通信管道中得到一个字节输出流,用来发送数据给服务程序
    10. OutputStream os = socket.getOutputStream();
    11. //把低级的字节输出流包装成数据输出流
    12. DataOutputStream dos = new DataOutputStream(os);
    13. //写入数据
    14. dos.writeUTF("hello!!!");
    15. //释放连接资源
    16. dos.close();
    17. socket.close();
    18. }
    19. }
    1. package learn14;
    2. import java.io.DataInputStream;
    3. import java.io.IOException;
    4. import java.io.InputStream;
    5. import java.net.ServerSocket;
    6. import java.net.Socket;
    7. public class ServerTCP {
    8. public static void main(String[] args) throws Exception {
    9. System.out.println("服务端启动成功");
    10. //创建ServerSocket对象
    11. ServerSocket serverSocket = new ServerSocket(8888);
    12. //使用ServerSocket对象
    13. Socket socket = serverSocket.accept();
    14. //从socket通信管道得到一个字节输入流
    15. InputStream is = socket.getInputStream();
    16. //把原始的字节输入流包装成数据输入流
    17. DataInputStream dis = new DataInputStream(is);
    18. //使用数据输入流读取客户端发送的消息
    19. String rs = dis.readUTF();
    20. System.out.println(rs);
    21. System.out.println(socket.getRemoteSocketAddress());
    22. dis.close();
    23. socket.close();
    24. }
    25. }

    多次发送,多次接收

    1. package learn14;
    2. import java.io.DataOutputStream;
    3. import java.io.OutputStream;
    4. import java.net.Socket;
    5. import java.util.Scanner;
    6. public class ClientTCP {
    7. public static void main(String[] args) throws Exception {
    8. //创建Socket对象
    9. Socket socket = new Socket("127.0.0.1", 8888);
    10. //从socket通信管道中得到一个字节输出流,用来发送数据给服务程序
    11. OutputStream os = socket.getOutputStream();
    12. //把低级的字节输出流包装成数据输出流
    13. DataOutputStream dos = new DataOutputStream(os);
    14. Scanner sc = new Scanner(System.in);
    15. //写入数据
    16. while (true) {
    17. System.out.println("请说:");
    18. String msg = sc.nextLine();
    19. if ("exit".equals(msg)) {
    20. System.out.println("退出成功,欢迎下次光临!");
    21. dos.close();
    22. socket.close();
    23. break;
    24. }
    25. dos.writeUTF(msg);
    26. dos.flush();
    27. }
    28. }
    29. }
    1. package learn14;
    2. import java.io.DataInputStream;
    3. import java.io.IOException;
    4. import java.io.InputStream;
    5. import java.net.ServerSocket;
    6. import java.net.Socket;
    7. public class ServerTCP {
    8. public static void main(String[] args) throws Exception {
    9. System.out.println("服务端启动成功");
    10. //创建ServerSocket对象
    11. ServerSocket serverSocket = new ServerSocket(8888);
    12. //使用ServerSocket对象
    13. Socket socket = serverSocket.accept();
    14. //从socket通信管道得到一个字节输入流
    15. InputStream is = socket.getInputStream();
    16. //把原始的字节输入流包装成数据输入流
    17. DataInputStream dis = new DataInputStream(is);
    18. //使用数据输入流读取客户端发送的消息
    19. while (true) {
    20. try {
    21. String rs = dis.readUTF();
    22. System.out.println(rs);
    23. System.out.println(socket.getRemoteSocketAddress());
    24. } catch (IOException e) {
    25. System.out.println(socket.getRemoteSocketAddress() + "离线了");
    26. dis.close();
    27. socket.close();
    28. break;
    29. }
    30. }
    31. }
    32. }

    多个客户端同时通信

    1. package learn14;
    2. import java.io.DataInputStream;
    3. import java.io.InputStream;
    4. import java.net.Socket;
    5. public class ServerReaderThead extends Thread {
    6. private Socket socket;
    7. public ServerReaderThead(Socket socket) {
    8. this.socket = socket;
    9. }
    10. @Override
    11. public void run() {
    12. try {
    13. InputStream is = socket.getInputStream();
    14. DataInputStream dis = new DataInputStream(is);
    15. while (true) {
    16. try {
    17. String msg = dis.readUTF();
    18. System.out.println(msg);
    19. } catch (Exception e) {
    20. System.out.println("有客户端下线了:" + socket.getRemoteSocketAddress());
    21. dis.close();
    22. socket.close();
    23. break;
    24. }
    25. }
    26. } catch (Exception e) {
    27. e.printStackTrace();
    28. }
    29. }
    30. }
    1. package learn14;
    2. import java.net.ServerSocket;
    3. import java.net.Socket;
    4. public class ServerTCP {
    5. public static void main(String[] args) throws Exception {
    6. System.out.println("服务端启动成功");
    7. //创建ServerSocket对象
    8. ServerSocket serverSocket = new ServerSocket(8888);
    9. //使用ServerSocket对象
    10. while (true) {
    11. Socket socket = serverSocket.accept();
    12. System.out.println("客户端上线了:"+socket.getRemoteSocketAddress());
    13. //将通信管道交给独立的线程处理
    14. new ServerReaderThead(socket).start();
    15. }
    16. }
    17. }
    1. package learn14;
    2. import java.io.DataOutputStream;
    3. import java.io.OutputStream;
    4. import java.net.Socket;
    5. import java.util.Scanner;
    6. public class ClientTCP {
    7. public static void main(String[] args) throws Exception {
    8. //创建Socket对象
    9. Socket socket = new Socket("127.0.0.1", 8888);
    10. //从socket通信管道中得到一个字节输出流,用来发送数据给服务程序
    11. OutputStream os = socket.getOutputStream();
    12. //把低级的字节输出流包装成数据输出流
    13. DataOutputStream dos = new DataOutputStream(os);
    14. Scanner sc = new Scanner(System.in);
    15. //写入数据
    16. while (true) {
    17. System.out.println("请说:");
    18. String msg = sc.nextLine();
    19. if ("exit".equals(msg)) {
    20. System.out.println("退出成功,欢迎下次光临!");
    21. dos.close();
    22. socket.close();
    23. break;
    24. }
    25. dos.writeUTF(msg);
    26. dos.flush();
    27. }
    28. }
    29. }

  • 相关阅读:
    树大总结(王道+红皮书)
    TensorDataset和DataLoader使用
    python爬虫之feapder.AirSpider轻量爬虫案例:豆瓣
    机器学习开源工具BatteryML,一站式分析与预测电池性能
    安装 Ubuntu 桌面服务与谷歌浏览器
    Spring Cloud Alibaba+saas企业架构技术选型+架构全景业务图 + 架构典型部署方案
    Redis 篇
    [Ext JS]图片显示方式
    TikTok达人解锁的条件
    CH9101国产USB转异步串口芯片兼容替代PL2303GC/PL2303HXD/FT230X/FT232RQ/CY7C65213
  • 原文地址:https://blog.csdn.net/MRJJ_9/article/details/133198179