• Java(十)(网络编程,UDP,TCP)


    目录

    网络编程

    两种软件架构

    网络通信的三要素

    IP

    IPv4的地址分类

    特殊IP

    端口号

    协议

    用UDP协议发送数据 

    用UDP接收数据

    TCP接收和发送数据

    TCP通信--支持与多个客户端同时通信


    网络编程

    可以让设备中的程序与网络上其他设备的程序进行数据交互(实现网络通信)

    两种软件架构

    CS:在用户本地需要下载并安装客户端程序,在远程有一个服务器端程序

    BS:只需要一个浏览器,用户通过不同的网址,客户访问不同的服务器

    网络通信的三要素

    IP

    设备在网络中的地址,是唯一的标识

    有IPv4和IPv6

    最多有2^32次方的ip,目前用完了

    IPv4中不够用,就有了IPv6

    为了解决ipv4不够用而出现的,最多有2^128次方的ip

    IPv4的地址分类

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

    192.168.开头的就是私有地址,范围即为192.168.0.0--192.168.255.255,专门为组织机构内部使用,以此节约IP

    特殊IP

    127.0.0.1,也可以是localhost:是回送地址也称本地回环地址,也成为本机IP,永远只会寻找当前所在的本机

    常用的CMD命令

    ipconfig:查看本机IP地址

    ping:检查网络是否连通

    1. public class ip {
    2. public static void main(String[] args) throws UnknownHostException {
    3. // 1.获取InetAddress的对象
    4. // IP的对象 一台电脑对象
    5. InetAddress address = InetAddress.getByName("192.168.135.1");
    6. System.out.println(address);
    7. String name = address.getHostName();
    8. System.out.println(name);
    9. String ip = address.getHostAddress();
    10. System.out.println(ip);
    11. }
    12. }

    端口号

    应用程序在设备中唯一的标识

    端口号: 由两个字节表示的整数,取值范围:0-665535,其中0-1023之间的端口用于一些知名的网络服务或应用,我们自己使用1024以上的端口就可以了

    协议

    数据在网路中传输的规则

    UDP协议: 用户数据报协议

    UDP是面向无连接通信协议

    速度快,有大小限制一次最多发送64K,数据不安全,易丢失数据

    TCP协议:传输控制协议

    TCP协议是面向连接的通信协议

    速度慢,没有大小限制,数据安全

    下面是用UDP来发收数据

    用UDP协议发送数据 
    1. public class ip {
    2. public static void main(String[] args) throws IOException {
    3. // 发送数据
    4. // 1.创建DatagramSocket对象
    5. // 细节:
    6. //绑定端口,以后我们就是通过这个端口往外发送
    7. //有参:指定端口号进行绑定
    8. DatagramSocket ds = new DatagramSocket();
    9. // 打包数据
    10. String str = "hello world";
    11. byte[] bytes = str.getBytes(); // 将str转换成字节数组来用来打包数据
    12. InetAddress address = InetAddress.getByName("127.0.0.1"); // 表示那台ip电脑来接受
    13. int port=10086; //被发数据电脑接收的端口
    14. DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);
    15. // 3. 发送数据
    16. ds.send(dp);
    17. // 4.释放资源
    18. ds.close();
    19. }
    20. }
    用UDP接收数据
    1. public class receive {
    2. public static void main(String[] args) throws IOException {
    3. // 接收数据
    4. // 1.创建DatagramSocket对象//我们可以做一个比喻: 这就是一个快递公司
    5. // 细节:
    6. // 接收和传输不一样:接收一定要绑定接口
    7. // 而且绑定的端口,一定要跟发送的端口保持一致
    8. DatagramSocket ds = new DatagramSocket(10086);
    9. // 2. 接收数据包
    10. byte[] bytes = new byte[1024];
    11. DatagramPacket dp = new DatagramPacket(bytes,bytes.length);
    12. ds.receive(dp);
    13. // 3.解析数据包
    14. byte[] data = dp.getData();
    15. int len = dp.getLength();
    16. InetAddress address = dp.getAddress();
    17. int port = dp.getPort();
    18. System.out.println("接收到数据" + new String(data,len));
    19. System.out.println("该数据是从"+address+"接口是"+port);
    20. // .释放资源
    21. ds.close();
    22. }
    23. }
    TCP接收和发送数据

    通信双方事先会采用"三次握手"方式建立可靠连接,实现端到端的通信;底层能保证数据成功传到服务端

    一发一收

    创建客户端

    1. import java.io.DataOutputStream;
    2. import java.io.IOException;
    3. import java.io.OutputStream;
    4. import java.net.Socket;
    5. public class Tcp {
    6. public static void main(String[] args) throws IOException {
    7. // 1.创建Socket对象,并同时请求与服务器程序的连接
    8. Socket socket = new Socket("127.0.0.1",8888);
    9. // 2.从socket通信管道中得到一个字节输出流,用来发数据给服务端程序
    10. OutputStream os = socket.getOutputStream();
    11. // 3.把低级的字节输出流包装成数据流
    12. DataOutputStream dos = new DataOutputStream(os);
    13. //4.开始写数据出去了
    14. dos.writeUTF("在一起,好吗?");
    15. dos.close();
    16. socket.close();
    17. }
    18. }

    创建服务器

    1. import java.io.DataInputStream;
    2. import java.io.IOException;
    3. import java.io.InputStream;
    4. import java.net.ServerSocket;
    5. import java.net.Socket;
    6. public class Res {
    7. public static void main(String[] args) throws IOException {
    8. System.out.println("------服务端启动成功------");
    9. // 1.创建ServerSocket的对象,同时为服务端注册端口
    10. ServerSocket serverSocket = new ServerSocket(8888);
    11. // 2.使用serverSocket对象,调用一个accept方法,等待客户端的连接请求
    12. Socket socket = serverSocket.accept();
    13. // 3. 从socket通信管道中得到一个字节输入流
    14. InputStream is = socket.getInputStream();
    15. //4.把原始的字节输入流包装成数据输入流
    16. DataInputStream dis = new DataInputStream(is);
    17. //5.使用数据输入流读取客户端发送的消息
    18. String rs = dis.readUTF();
    19. System.out.println(rs);
    20. // 其实我们也可以获取客户端的IP地址
    21. System.out.println(socket.getRemoteSocketAddress());
    22. dis.close();
    23. socket.close();
    24. }
    25. }

    多发多收

    发送数据

    1. import java.io.DataOutputStream;
    2. import java.io.IOException;
    3. import java.io.OutputStream;
    4. import java.net.Socket;
    5. import java.util.Scanner;
    6. public class Tcp {
    7. public static void main(String[] args) throws IOException {
    8. // 1.创建Socket对象,并同时请求与服务器程序的连接
    9. Socket socket = new Socket("127.0.0.1",8888);
    10. // 2.从socket通信管道中得到一个字节输出流,用来发数据给服务端程序
    11. OutputStream os = socket.getOutputStream();
    12. // 3.把低级的字节输出流包装成数据流
    13. DataOutputStream dos = new DataOutputStream(os);
    14. Scanner sc = new Scanner(System.in);
    15. while (true) {
    16. System.out.println("请说: ");
    17. String msg = sc.nextLine();
    18. // 一旦用户输入exit,就退出客户端程序
    19. if("exit".equals(msg)){
    20. System.out.println("欢迎你下次光临!退出成功");
    21. dos.close();
    22. socket.close();
    23. break;
    24. }
    25. //4.开始写数据出去了
    26. dos.writeUTF(msg);
    27. dos.flush();
    28. }
    29. }
    30. }

    接收数据

    1. import java.io.DataInputStream;
    2. import java.io.IOException;
    3. import java.io.InputStream;
    4. import java.net.ServerSocket;
    5. import java.net.Socket;
    6. public class Res {
    7. public static void main(String[] args) throws IOException {
    8. System.out.println("------服务端启动成功------");
    9. // 1.创建ServerSocket的对象,同时为服务端注册端口
    10. ServerSocket serverSocket = new ServerSocket(8888);
    11. // 2.使用serverSocket对象,调用一个accept方法,等待客户端的连接请求
    12. Socket socket = serverSocket.accept();
    13. // 3. 从socket通信管道中得到一个字节输入流
    14. InputStream is = socket.getInputStream();
    15. //4.把原始的字节输入流包装成数据输入流
    16. DataInputStream dis = new DataInputStream(is);
    17. while (true) {
    18. try {
    19. //5.使用数据输入流读取客户端发送的消息
    20. String rs = dis.readUTF();
    21. System.out.println(rs);
    22. } catch (IOException e) {
    23. System.out.println(socket.getRemoteSocketAddress()+"离线了");
    24. socket.close();
    25. dis.close();
    26. break;
    27. }
    28. }
    29. }
    30. }
    TCP通信--支持与多个客户端同时通信

    我们应该整一个多线程的写法,每个客户端写成一个线程

    创建客户端

    1. public class tcp {
    2. public static void main(String[] args) throws IOException {
    3. Socket socket = new Socket("127.0.0.1",9999);
    4. OutputStream os = socket.getOutputStream();
    5. DataOutputStream dos = new DataOutputStream(os);
    6. // 1. 多发多收
    7. Scanner sc = new Scanner(System.in);
    8. while (true) {
    9. String msg = sc.nextLine();
    10. if("886".equals(msg)){
    11. System.out.println("下线");
    12. break;
    13. }
    14. dos.writeUTF(msg);
    15. }
    16. }
    17. }

    创建服务端

    1. public class res {
    2. public static void main(String[] args) throws IOException {
    3. ServerSocket serverSocket =new ServerSocket(9999);
    4. while (true) {
    5. Socket socket = serverSocket.accept();
    6. System.out.println("有人上线了"+socket.getRemoteSocketAddress());
    7. new SeverSocketThread(socket).start();
    8. }
    9. }
    10. }

    我们看看线程的写法

    1. package TCP_test;
    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 SeverSocketThread extends Thread{
    8. private Socket socket;
    9. public SeverSocketThread(Socket socket) {
    10. this.socket = socket;
    11. }
    12. @Override
    13. public void run()
    14. {
    15. try {
    16. InputStream is = socket.getInputStream();
    17. DataInputStream dis = new DataInputStream(is);
    18. while (true) {
    19. try {
    20. String msg = dis.readUTF();
    21. System.out.println(msg);
    22. } catch (Exception e) {
    23. System.out.println("有人下线了"+socket.getRemoteSocketAddress());
    24. dis.close();
    25. is.close();
    26. socket.close();
    27. break;
    28. }
    29. }
    30. } catch (IOException e) {
    31. System.out.println(socket.getRemoteSocketAddress() + "下线");
    32. }
    33. }
    34. }

  • 相关阅读:
    ChatGPT 和 Elasticsearch:APM 工具、性能和成本分析
    9、传统计算机视觉 —— 边缘检测
    VMware16+Ubuntu20.04搭建Vulhub
    【JavaScript进阶之旅 ES6篇 第十章】操作原型的方法、super、4种遍历方式、Symbol
    用webwoker解决客服系统业务上的问题
    CAS:851113-28-5 (生物素-ahx-ahx-酪胺)
    c++以exception_ptr传递异常
    Semantic Kernel入门系列:利用YAML定义prompts functions
    学习笔记-算法-9-二叉树-1
    组件框架网站+demo库+svg库+渐变色库网站+矢量图网站等等
  • 原文地址:https://blog.csdn.net/2201_75442971/article/details/134670941