第二十一章 网络通信

news2025/1/23 17:46:09

网络通信这一章  基本分为三个部分  网络基础概念和TCP,UDP这三个部分主要如下:

计算机网络实现了堕胎计算机间的互联,使得它们彼此之间能够进行数据交流。网络应用程序就是再已连接的不同计算机上运行的程序,这些程序借助于网络协议,相互之间可以交换数据,编写网络应用程序前,首先必须明确网络协议TCP/IP协议是网络应用程序的首选

网络程序设计基础:

网络程序设计编写始于其他计算机进行通信的程序,java已经将网络程序所需要而定元素封装成不同的类,用户只要床啊金这些类的对象,使用相应的方法即使不举报相关的网络知识,也是可以编写除高质量的网络通信程序的,

本章最主要的是TCP和UDP两个部分  他们两主要的区别就是一个是一对一通信  一个是一对多通信   当然两者都有各自的优势和劣势,接下来先讲解 TCP部分
TCP程序

TCP程序的通信方式呢 是一对一的   步骤是  先要打开服务器然后客户端连接服务器  先是尝试客户端是否能够接收到信息  如果可以接收到信息的话  这时服务器将会把文件传输给客户端,这样的话 能够保证客户端可以接收到信息  ,劣势呢就是每次都是要这样子 所以效率对比起UDP来说慢下了好多  以下代码将会进行讲解

客户端代码:

package tcp;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/**
 * Socket客户端
 **/
public class SocketClient {
    public static void main(String[] args) {
        Socket s = null;
        try {
            // 与ip为127.0.0.1、端口为12345的服务端建立连接
            s = new Socket("127.0.0.1", 12345);

            // 创建输入流接收服务端发送的消息(字节流)
            InputStream is = s.getInputStream();
            // 将服务端返回的字节流转化为字符流
            InputStreamReader isr = new InputStreamReader(is);
            // 创建字符流读取缓冲区,方便每行读取
            BufferedReader br = new BufferedReader(isr);

            // 创建输出流返回消息
            OutputStream os = s.getOutputStream();
            // 创建输出流缓冲
            PrintWriter pw = new PrintWriter(os);

            // 创建发送消息的线程
            Runnable rOut = () -> {
                boolean flag = true;
                while (flag) {
                    try {
                        // 接收控制台输入
                        Scanner scan = new Scanner(System.in);
                        String msg = scan.nextLine();
                        // 将输入写入缓冲
                        pw.println(msg);
                        // 将缓冲内的数据推送至服务端并清空缓冲区
                        pw.flush();
                    } catch (Exception e) {
                        flag = false;
                        e.printStackTrace();
                    }
                }
            };

            // 创建接收消息的线程
            Runnable rIn = () -> {
                boolean flag = true;
                while (flag) {
                    try {
                        // 逐行读取服务端返回的消息并打印
                        String str = br.readLine();
                        System.out.println("服务端的消息:" + str);
                    } catch (IOException e) {
                        flag = false;
                        e.printStackTrace();
                    }
                }
            };

            // 启动两个线程
            Thread tOut = new Thread(rOut);
            Thread tIn = new Thread(rIn);
            tOut.start();
            tIn.start();
        }catch (IOException e) {
            try {
                // 释放资源
                s.close();
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            e.printStackTrace();
        }
    }
}

 服务端代码:

package tcp;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
 * Socket服务端
 **/
public class SocketServer {
    public static void main(String[] args) {
        ServerSocket ss = null;
        Socket s = null;
        try {
            // 创建监听端口为12345的Socket服务端
            ss = new ServerSocket(12345);
            System.out.println("服务端Socket服务已建立,等待客户端连接...");
            // 通过ss.accept()开始持续监听12345端口,当有连接时获取收到的包装成Socket的客户端对象
            s = ss.accept();
            // 获取客户端的IP地址和端口号
            String ip = s.getInetAddress().getHostAddress();
            int port = s.getPort();
            System.out.println("服务端与 " + ip + ":" + port + " 已建立连接");

            // 创建输入流接收客户端发送的消息(字节流)
            InputStream is = s.getInputStream();
            // 将客户端发送的字节流转化为字符流
            InputStreamReader isr = new InputStreamReader(is);
            // 创建字符流读取缓冲区,方便每行读取
            BufferedReader br = new BufferedReader(isr);

            // 创建输出流返回消息
            OutputStream os = s.getOutputStream();
            // 创建输出流缓冲
            PrintWriter pw = new PrintWriter(os);

            // 创建接受信息的线程
            Runnable rIn = () -> {
                boolean flag = true;
                while (flag) {
                    try {
                        // 逐行读取客户端发送的消息并打印
                        String str = br.readLine();
                        System.out.println("客户端的消息:" + str);
                    } catch (IOException e) {
                        flag = false;
                        e.printStackTrace();
                    }
                }
            };

            // 创建发送消息的线程
            Runnable rOut = () -> {
                boolean flag = true;
                while (flag) {
                    try {
                        // 接收控制台输入
                        Scanner scan = new Scanner(System.in);
                        String msg = scan.nextLine();
                        // 将输入写入缓冲
                        pw.println(msg);
                        // 将缓冲内的数据推送至客户端并清空缓冲区
                        pw.flush();
                    } catch (Exception e) {
                        flag = false;
                        e.printStackTrace();
                    }
                }
            };

            // 开启两个线程
            Thread tIn = new Thread(rIn);
            Thread tOut = new Thread(rOut);
            tIn.start();
            tOut.start();
        } catch (IOException e) {
            try {
                // 释放资源
                ss.close();
                s.close();
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            e.printStackTrace();
        }
    }
}

 代码图如下:

运行结果如下所示:

 

 接下来讲解UDP程序

UDP程序

UDP程序跟TCP程序不同的地方呢  TCP通信是一对一通信 如果要一下通知好多个人的话 就需要一个一个来通信  所以这时将会需要UDP了  UDP的优势就在于效率高 但是不稳定的地方呢  就是效率高但是不一定每个人都能看到  就像老师在台上讲课 总有一些学生会在台下玩手机 或者带耳机  不一定每一个人都能够接受得到  这就是UDP的不稳定的地方 ,接下来使用代码来讲解:

广播类代码如下:

package udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
//广播  先运行
public class Notification  extends Thread{
	String weather = "节目预报:八点有大型晚会,请收听";//发送消息
	int port = 9898;//端口号
	InetAddress iaddress = null;
	MulticastSocket socket = null;//多点广播套接字
	
	Notification(){
		try {
			iaddress = InetAddress.getByName("224.255.10.0");//地址
			socket = new MulticastSocket(port);//实例化多点广播套接字
			socket.setTimeToLive(1);//指定发送范围是本地网络
			socket.joinGroup(iaddress);//加入广播组
		}catch(IOException e){
			e.printStackTrace();//输出异常信息
		}
	
	}
	public void run(){//run方法
		while(true) {
			DatagramPacket packet = null;//数据包
			byte data[]=weather.getBytes();//字符串消息的字节数组
			packet =  new  DatagramPacket(data,data.length,iaddress,port);//将数据打包
			System.out.println(weather);//控制台打印消息
			try {
				socket.send(packet);//发送数据
				sleep(3000);//让线程休眠3000毫秒
			}catch(IOException e){
				e.printStackTrace();
			}catch(InterruptedException e) {
				e.printStackTrace();
			}
		}	
			}
	public static void main(String[]args) {
		Notification w =new Notification();
		w.start();//启动线程
	}
}

接收类代码如下:

package udp;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;
//接收  后运行
public class Receive extends JFrame implements Runnable, ActionListener {
	int port ;//端口
	InetAddress group =null;//广播组地址
	MulticastSocket socket = null;//多点广播套接字对象
	JButton inceBtn = new JButton("开始接收");
	JButton stopBtn = new JButton("停止接收");
	JTextArea inceAr = new JTextArea(10,10);//显示接收广播的文本域
	JTextArea inced = new JTextArea(10,10);
	Thread thread ;
	boolean stop = false;//定制接受信息状态
	
	public Receive () {
		setTitle("广播数据包");
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		thread = new Thread(this);
		inceBtn.addActionListener(this);//绑定按钮ince的单击事件
		stopBtn.addActionListener(this);//绑定按钮stop的单击事件
		inceAr.setForeground(Color.blue);//指定文本域中文字的颜色
		
		JPanel north = new JPanel();
		north.add(inceBtn);//将按钮添加到面板north上
		north.add(stopBtn);
		add(north,BorderLayout.NORTH);//将north放置在窗体的上部
		JPanel center = new JPanel();//创建面板对象center
		center.setLayout(new GridLayout(1,2));//设置面板布局
		center.add(inceAr);//将文本域添加到面板上
		center.add(inced);
		add(center,BorderLayout.CENTER);//设置面板的布局
		validate();//刷新
		port =9898;//设置端口号
		try {
			group = InetAddress.getByName("224.255.10.0");//指定接收地址
			socket = new MulticastSocket(port);//绑定多点广播套接字
			socket.joinGroup(group);//加入广播组
		}catch(IOException e){
			e.printStackTrace();//输出异常信息
		}
		setBounds(100,50,360,380);//设置布局
		setVisible(true);//将窗体设置为显示状态
	}
	public void run() {//run方法
		while (!stop) {
			byte data[] = new byte[1024];//创建缓存字节数组
			DatagramPacket packet = null;
			packet = new  DatagramPacket(data,data.length,group,port);//待接收的数据包
			try {
				socket.receive(packet);//接收数据包
				//获取数据包中的内容
				String message  = new String(packet.getData(),0,packet.getLength());
				inceAr.setText("正在接收的内容:\n"+message);//将接受内容显示在文本域中
				inced.append(message+"\n");//每条信息为一行
			}catch(IOException e ) {
				e.printStackTrace();//输出异常信息
			}
			
		}
	}
	public void actionPerformed(ActionEvent e) {//单机按钮ince出发时间
		if(e.getSource()==inceBtn) {
			inceBtn.setBackground(Color.red);//设置按钮颜色
			stopBtn.setBackground(Color.yellow);
			if(!(thread.isAlive())) {//如线程不处于“新建状态”
				thread = new Thread(this);//实例化Thread对象
			}
			thread.start();//启动线程
			stop = false;//开始接受信息
		}
		if(e.getSource()== stopBtn) {//单机按钮stop出发时间
			inceBtn.setBackground(Color.yellow);//设置按钮亚瑟
			stopBtn.setBackground(Color.red);
			stop = true;//停止接收信息
		}
	}
	public static void main(String[]args) {
		Receive rec = new Receive();
		rec.setSize(460,200);
	}
}

代码图如下所示:

运行结果如下所示:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1289811.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想Day24 | 回溯法模板、77. 组合

理论基础 回溯法和递归不可分割,回溯法是一种穷举的方法,通常需要剪枝来降低复杂度。回溯法有一个选择并退回的过程,可以抽象为树结构,回溯法的模板如下: void backtracking(参数) {if (终止条件) {存放结果;return;}…

【从0配置JAVA项目相关环境1】jdk + VSCode运行java + mysql + Navicat + 数据库本地化 + 启动java项目

从0配置JAVA项目相关环境 写在最前面一、安装Java的jdk环境1. 下载jdk2. 配置jdk3. 配置环境变量 二、在vscode中配置java运行环境1. 下载VSCode2. 下载并运行「Java Extension Pack」 三、安装mysql1.官网下载MySQL2.开始安装如果没有跳过安装成功 3.配置MySQL Server4.环境变…

InST论文复现

论文地址:https://arxiv.org/abs/2211.13203 论文git:https://github.com/zyxElsa/InST 遇到的问题: 1.requests.exceptions.SSLError: HTTPSConnectionPool(hosthuggingface.co, port443): Max retries exceeded with url: /openai/clip-…

机器学习 | RMSE和R平方误差的数学解释

RMSE:均方根误差是回归线拟合数据点的程度的度量。RMSE也可以解释为残差中的标准差。 考虑给定的数据点:(1,1),(2,2),(2,3&#xff09…

java WebSocket带参数处理使用

1、webSocket实现代码 Component public class WebSocketStompConfig {//这个bean的注册,用于扫描带有ServerEndpoint的注解成为websocket// ,如果你使用外置的tomcat就不需要该配置文件Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpoi…

三十八、AT模式

目录 一、定义 1、AT模式工作原理如下: 2、优点: 3、缺点: 4、流程: 二、AT模式与XA模式的区别 三、AT模式的脏写问题 四、实现AT模式 一、定义 AT模式是指使用AT命令进行串口通信的工作模式。AT命令是由两个字符组成的命…

协同过滤算法之vue+springboot个性化电影评分推荐系统6n498

摘要为了解决信息过载问题,个性化推荐系统由此产生。个性化推荐系统通过对用户行为的分析,利用数据挖掘算法对信息进行过滤,将用户可能感兴趣的产品或项目推荐给用户。对于电影爱好者来说,利用网络在浩如烟海的电影数据库中找到自己喜欢的电影并非易事。电影作为一个艺术的载体…

ahk系列-windows超级运行框-表达式计算(6)—asc/ord/chr ASCII 码转换

1、环境准备 windows 7,8,10,11操作系统ahk 2.x_64位 2、使用方式 asc 可以计算 asc字符 ,或者汉字,的数值,ord /chr 则是把数值转换为字符 当然有很多字符不可见,比如我们用 “{}” 包裹它…

软件测试之python+requests接口自动化测试框架实例教程

前段时间由于公司测试方向的转型,由原来的web页面功能测试转变成接口测试,之前大多都是手工进行,利用postman和jmeter进行的接口测试,后来,组内有人讲原先web自动化的测试框架移驾成接口的自动化框架,使用的…

元宇宙解决方案:GPU云服务在元宇宙中的作用

GPU算力可以说是我们现在信息化时代的基础设施,在某种程度上说我们已经进入了算力时代,手机、电脑、车载等算力已经渗透到各行各业了。 当然算力对元宇宙也很重要,尤其是在可视化方面,元宇宙需要很逼真的渲染,同时它的…

【8】PyQt单选框和复选框

目录 1. 单选框 2. 复选框 1. 单选框 QRadioButton是单选按钮,它提供了一组可供选择的按钮和文本标签,用户可以选择其中一个选项 单选框选中的信号是:toggled 代码示例: from PyQt5.QtWidgets import * from PyQt5.QtCore import * import sysdef func(checked…

校园教务管理系统

学年论文(课程设计) 题目: 信息管理系统 校园教务管理系统 摘要:数据库技术是现代信息科学与技术的重要组成部分,是计算机数据处理与信息管理系统的核心,随着计算机技术的发展,数据库技…

docker:安装mysql以及最佳实践

文章目录 1、拉取镜像2、运行容器3、进入容器方式一方式二方式三容器进入后连接mysql和在宿主机连接mysql的区别 持久化数据持久化数据最佳实践 1、拉取镜像 docker pull mysql2、运行容器 docker run -d -p 3307:3306 --name mysql-container -e MYSQL_ROOT_PASSWORD123456 …

Python实现FA萤火虫优化算法优化随机森林回归模型(RandomForestRegressor算法)项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 萤火虫算法(Fire-fly algorithm,FA)由剑桥大学Yang于2009年提出 , …

意大利语翻译成中文怎样做比较好

近年来,中意两国传统友好,两国人民之间的交往源远流长,双方合作不断推进,国内市场对于意大利语翻译的需求日益增加。那么,意大利语翻译有何特点,意大利语翻译成中文怎样做比较好呢? 由于意大利语…

matlab实践(十):贝塞尔曲线

1.贝塞尔曲线 贝塞尔曲线的原理是基于贝塞尔曲线的数学表达式和插值算法。 贝塞尔曲线的数学表达式可以通过控制点来定义。对于二次贝塞尔曲线,它由三个控制点P0、P1和P2组成,其中P0和P2是曲线的起点和终点,P1是曲线上的一个中间点。曲线上…

Leetcode每日一题学习训练——Python3版(最小化旅行的价格总和)

版本说明 当前版本号[20231206]。 版本修改说明20231206初版 目录 文章目录 版本说明目录最小化旅行的价格总和理解题目代码思路参考代码 原题可以点击此 2646. 最小化旅行的价格总和 前去练习。 最小化旅行的价格总和 现有一棵无向、无根的树,树中有 n 个节点…

LeetCode Hot100 207.课程表

题目: 你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习…

人工智能在警务工作中的运用

AI 能否帮助警察打击犯罪? 执法部门负责维护公共安全,他们必须处理随之而来的所有挑战。幸运的是,警察可以依靠技术来处理很多工作。近几年来,尤其是人工智能技术在全球变成了警务工作中的一个重要部分。 随着基于 AI 的警务技术…

如何在Java中实现多条件排序

文章目录 前言一、在Java中使用Comparator接口实现多条件排序二、视频讲解总结 前言 多条件排序是一个复杂而实用的技术问题,它涉及到算法、数据结构等多个领域。 在实际工作中,我们常常需要根据多个条件对数据进行排序,以达到最优化的效果。…