当前位置: 首页 > news >正文

Java高级编程—网络编程(完整详解,包括UDP通信方式、TCP通信方式、TCP三次握手、TCP四次挥手,附有代码+案列)

文章目录

  • 二十九.网络编程
    • 29.1 概述
    • 29.2 InetAddress
    • 29.3 UDP通信
      • 29.3.1 UDP通信发送数据
      • 29.3.2 UDP通信接收数据
      • 29.3.3 Test
    • 29.4 UDP的三种通信方式
      • 29.4.1 单播
      • 29.4.2 组播
      • 29.4.3 广播
    • 29.5 TCP通信
    • 29.6 TCP通信三次握手
    • 29.7 TCP通信四次挥手
    • 29.8 Test
      • 29.8.1 多次发送

二十九.网络编程

29.1 概述

网络编程三要素

  • IP:设备在网络中的地址,是唯一标识的
  • 端口号:应用程序在设备中的唯一标识(0-65535)
  • 协议:数据在网络中传输的规则(UDP、TCP、http…)

29.2 InetAddress

static InetAddress getByName(String host) 
确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址String getHostName()              获取此IP地址的主机名
String getHostAddress()           返回文本显示中的IP地址字符串

(遇见异常直接抛,默认采用alt+enter提示的第一种方式处理异常)

import java.net.InetAddress;
import java.net.UnknownHostException;public class Test01 {public static void main(String[] args) throws UnknownHostException {InetAddress mykwh = InetAddress.getByName("mykwh");System.out.println(mykwh);//mykwh/169.254.146.8String hostAddress = mykwh.getHostAddress();System.out.println(hostAddress);//169.254.146.8String hostName = mykwh.getHostName();System.out.println(hostName);//mykwh}
}

29.3 UDP通信

29.3.1 UDP通信发送数据

  • 创建发送端的DatagramSocket对象
  • 数据打包(DatagramPacket)
  • 发送数据
  • 释放资源

(遇见异常直接抛,默认采用alt+enter提示的第一种方式处理异常)

import java.io.IOException;
import java.net.*;public class Test02 {public static void main(String[] args) throws IOException {// 1.创建发送端的DatagramSocket对象(相当于快递公司)//绑定端口,以后我们就是通过这个端口往外发送//空参:所有可用的端口中随机一个进行使用//有参:指定端口号进行绑定DatagramSocket ds = new DatagramSocket();//2. 数据打包(DatagramPacket)String str = "你好";//2.1 把字符串变成字节数组byte[] bytes = str.getBytes();//向127.0.0.1的设备发送InetAddress address = InetAddress.getByName("127.0.0.1");//2.2发送到某目的地的端口号int port = 10011;//2.3 打包发送DatagramPacket dp = new      DatagramPacket(bytes,bytes.length,address,port);// 3.发送数据ds.send(dp);// 4.释放资源ds.close();}
}

29.3.2 UDP通信接收数据

  • 创建接收端的DatagramSocket对象
  • 接收打包好的数据
  • 解析数据包
  • 释放资源

注意:必须先执行29.3.1中的发送数据代码,再执行接收数据代码

(遇见异常直接抛,默认采用alt+enter提示的第一种方式处理异常)

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class ReceiveMessTest {public static void main(String[] args) throws IOException {// 1.创建接收端的DatagramSocket对象,// 参数与发送端的端口号保持一致DatagramSocket ds = new DatagramSocket(10011);// 2.接收数据包// 2.1 新建数组用来接收数据(相当于用一个新的箱子来装数据)byte[] bytes = new byte[1024];// 2.2用bytes接收收据,并且用bytes所有的空间来接收DatagramPacket dp = new DatagramPacket(bytes,bytes.length);// 2.3 接收//receive方法是阻塞的//程序执行到这一步的时候,会在这里死等//等发送端发送消息ds.receive(dp);// 3.解析数据包// 3.1 将数据包(即 bytes数组)里的数据解析到数组databyte[] data = dp.getData();//获取当前接收到多少字节数据int length = dp.getLength();// 获取发送设备的ipInetAddress address = dp.getAddress();// 获取发送设备的端口号int port = dp.getPort();System.out.println("接收的数据是:"+ new String(data,0,length));System.out.println("接收数据是从"+address+"这个设备的"+port+"端口号发出的");}
}

29.3.3 Test

UDP发送:输入ending时结束发送

UDP接收:因不知发送端何时停止发送,故采用死循环接收

import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class SendMessTest {public static void main(String[] args) throws IOException {// 1.创建发送端对象DatagramSocket ds = new DatagramSocket();// 2.打包数据Scanner sc = new Scanner(System.in);while (true) {System.out.println("请输入要发送的数据:");String str = sc.nextLine();if("ending".equals(str)){break;}byte[] bytes = str.getBytes();InetAddress address = InetAddress.getByName("127.0.0.1");int port = 10011;DatagramPacket dp = new  DatagramPacket(bytes,bytes.length,address,port);// 3.发送数据ds.send(dp);}// 4.释放资源ds.close();}
}
=====================================================
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;public class ReceiveMessTest {public static void main(String[] args) throws IOException {// 1.创建接收端的DatagramSocket对象,DatagramSocket ds = new DatagramSocket(10011);//2. 创建接收数据的数据包byte[] bytes = new byte[1024];DatagramPacket dp = new DatagramPacket(bytes,bytes.length);while (true) {// 3.接收数据ds.receive(dp);// 4.解析数据包byte[] data = dp.getData();int port = dp.getPort();String ip = dp.getAddress().getHostAddress();String name = dp.getAddress().getHostName();int len = dp.getLength();// 5.打印数据System.out.println("ip为:"+ip+",主机为:"+name+",端口号为:"+port+",的设备发送了"+ new String(data,0,len));}}
}

29.4 UDP的三种通信方式

单薄、组播、广播

29.4.1 单播

//单播:创建DatagramSocket对象形式
DatagramSocket ds = new DatagramSocket();

29.4.2 组播

组播地址:224.0.0.0 ~ 239.255.255.255

其中:224.0.0.0 ~ 224.0.0.255为预留的组播地址,自己用预留的组播地址。

创建MulticastSocket接收端对象
MulticastSocket ms = new MulticastSocket(10011);
public class SendMessTest {public static void main(String[] args) throws IOException {// 组播发送端//1.创建MulticastSocket发送端对象MulticastSocket ms = new MulticastSocket() ;//2. 数据打包(DatagramPacket)// 2.1要打包的数据,即发送的剧数据String str = "追风赶月莫停留,平芜尽处是春山";// 2.2 将发送的字符串数据变成字符数组byte[] bytes = str.getBytes();// 2.3 向这个地址的内的设备发送InetAddress address = InetAddress.getByName("224.0.0.6");//2.4向10011端口发送int port = 10011;// 2.5 打包数据,DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);// 3.调用MulticastSocket发送数据方法发送数据ms.send(dp);// 4.释放资源ms.close();}
}
======================================================public class ReceiveMessTest01 {public static void main(String[] args) throws IOException {// 组播接收端1//1. 创建MulticastSocket接收端对象MulticastSocket ms = new MulticastSocket(10011);// 2. 将将当前本机,添加到224.0.0.6的这一组当中InetAddress address = InetAddress.getByName("224.0.0.6");ms.joinGroup(address);// 3.接收数据包// 3.1 新建数组用来接收数据(相当于用一个新的箱子来装数据)byte[] bytes = new byte[1024];// 3.2用bytes接收收据,并且用bytes所有的空间来接收DatagramPacket dp = new DatagramPacket(bytes,bytes.length);//4. 接收数据ms.receive(dp);// 5.解析数据// 将数据包(即 bytes数组)里的数据解析到数组databyte[] data = dp.getData();//获取当前接收到多少字节数据int len = dp.getLength();// 获取发送设备的端口号int port = dp.getPort();// 获取发送设备的ip和名字String ip = dp.getAddress().getHostAddress();String name = dp.getAddress().getHostName();System.out.println("ip为:" + ip +",主机名为:" + name + "的人,发送了数据:" + new String(data,0,len));//6. 释放资源ms.close();}
}
======================================================public class ReceiveMessTest02 {public static void main(String[] args) throws IOException {// 组播接收端2//1. 创建MulticastSocket接收端对象MulticastSocket ms = new MulticastSocket(10011);// 2. 将将当前本机,添加到224.0.0.6的这一组当中InetAddress address = InetAddress.getByName("224.0.0.6");ms.joinGroup(address);// 3.接收数据包// 3.1 新建数组用来接收数据(相当于用一个新的箱子来装数据)byte[] bytes = new byte[1024];// 3.2用bytes接收收据,并且用bytes所有的空间来接收DatagramPacket dp = new DatagramPacket(bytes,bytes.length);//4. 接收数据ms.receive(dp);// 5.解析数据// 将数据包(即 bytes数组)里的数据解析到数组databyte[] data = dp.getData();//获取当前接收到多少字节数据int len = dp.getLength();// 获取发送设备的端口号int port = dp.getPort();// 获取发送设备的ip和名字String ip = dp.getAddress().getHostAddress();String name = dp.getAddress().getHostName();System.out.println("ip为:" + ip +",主机名为:" + name + "的人,发送了数据:" + new String(data,0,len));//6. 释放资源ms.close();}
}

29.4.3 广播

广播地址:255.255.255.255

InetAddress address = InetAddress.getByName("127.0.0.1");
将单播发送数据中的这行代码中的 127.0.0.1 改成 255.255.255.255 即可

29.5 TCP通信

  • TCP 通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象,但是传输速度慢;面向连接。
  • 通信之前保证连接已经建立
  • 通过Sock产生IO流来进行网络通信
    (图片来自B站Java视频)
    在这里插入图片描述
    在这里插入图片描述

客户端(Socket):

  • 创建客户端的Sock对象(Socket)与指定服务端连接

    Socket ( String host, int port)

  • 获取输出流,写出数据

    OutputStream getOutputStream( )

  • 释放资源

    void close( )

服务器端(ServerSocket):

  • 创建服务器端的Socket对象(ServerSocket)

    ServerSocket(int port)

  • 监听客户端连接,返回一个Socket对象

    Socket accept( )

  • 获取输入流,读取数据,并把数据显示在控制台

    InputStream getInputStream( )

  • 释放资源

    void close( )

运行时要先运行服务端

//客户端,TCP协议,发送数据
public class Client {public static void main(String[] args) throws IOException {//TCP协议,发送数据// 创建Socket对象(客户端)//在创建对象的同时会连接服务端的ip:127.0.0.1Socket socket = new Socket("127.0.0.1",10011);// 连接成功后可从连接通道中获取(字节)输出流OutputStream os = socket.getOutputStream();// 写出数据,写出是字节数据String str = "aa666";os.write(str.getBytes());// 释放资源os.close();socket.close();//在释放资源时,底层会利用四次挥手协议断开连接,保证连接通道里面的数据已经处理完毕。}
}
=======================================================//服务器端, TCP协议,接收数据
public class Server {public static void main(String[] args) throws IOException {//TCP协议,接收数据// 1.创建服务端的对象,绑定客户端的端口ServerSocket ss = new ServerSocket(10011);//2. 监听客户端的连接//如果没有客户端连接,会死等//如果有客户端连接,会返回客户端的连接对象Socket socket = ss.accept();// 3.从连接通道中获取(字节)输入流读取数据InputStream is = socket.getInputStream();// 利用转换流 转成字符转换输入流,保证读取中文不乱码InputStreamReader isr  = new InputStreamReader(is);//还可可以将用缓冲流包装,用来提升读取效率BufferedReader br = new BufferedReader(isr);// 3.1 定义读取的字节数据int b ;//3.2 循环读取while ((b =is.read()) != -1){System.out.println((char) b);}// 4.释放资源// 4.1断开跟客户端的连接socket.close();// 4.2相当于关闭了服务器ss.close();}
}

29.6 TCP通信三次握手

(图片来自B站Java视频)
在这里插入图片描述

29.7 TCP通信四次挥手

(图片来自B站Java视频)
在这里插入图片描述

29.8 Test

29.8.1 多次发送

客户端:多次发送数据
服务器:接收多次接收数据,并打印
public class Client {public static void main(String[] args) throws IOException {//客户端:多次发送数据//服务器:接收多次接收数据,并打印// 创建Socket对象并连接服务端Socket socket = new Socket("127.0.0.1",10011);// 获取字节输出流,写出数据OutputStream os = socket.getOutputStream();Scanner sc = new Scanner(System.in);while (true) {System.out.println("请输入您要发送的信息:");String s = sc.nextLine();if ("ending".equals(s)){break;}os.write(s.getBytes());}//	释放资源os.close();socket.close();}
}
===========================================public class Server {public static void main(String[] args) throws IOException {//客户端:多次发送数据//服务器:接收多次接收数据,并打印//1.创建服务器端对象绑定10011端口ServerSocket ss = new ServerSocket(10011);//2.等待客户端来连接Socket sock = ss.accept();// 读取数据// 字节输入流InputStream is = sock.getInputStream();// 转成字符输入流InputStreamReader isr = new InputStreamReader(is);//字符缓冲流BufferedReader br = new BufferedReader(isr);int b ;while ((b= isr.read()) != -1){System.out.print((char) b);}// String line;// while ((line = br.readLine()) != null){//     System.out.println(line);// }//释放资源ss.close();}
}

http://www.mrgr.cn/news/22113.html

相关文章:

  • ④JdbcTemplate与声明式事务
  • MATLAB绘图基础6:MATLAB绘图基础
  • 仕考网:2025年公务员国考备考技巧
  • FastAPI数据模型:使用FormData extra参数防止数据污染
  • Python——将原来的gt.txt文件存为gt_原始.txt,修改后的文件作为 gt.txt
  • 基于Java+SpringBoot+Vue+MySQL的西安旅游管理系统网站
  • 828华为云征文|华为云Flexus云服务器X实例之openEuler系统下部署GitLab服务器
  • 开题报告中的研究方法设计:AI能帮你做什么?
  • 【Linux】进程控制(一)
  • 攻防世界--->你好,CTF
  • 使用协程实现高并发的I/O处理
  • 怎么仿同款小程序的开发制作方法介绍
  • RedNet 复现记录
  • 【进程间通信】System V--消息队列和信号量
  • 还不会剪音乐?试试这四款在线音频剪辑
  • JVM - GC垃圾回收
  • 【docker】通过云服务器安转Docker
  • 2024年土建施工员考试题库及答案
  • SprinBoot+Vue公交智能化系统的设计与实现
  • SwiftUI 中如何花样玩转 SF Symbols 符号动画和过渡特效