第二十一章,网络通信

网络协议

IP协议

IP是Internet Protocol的简称,是一种网络协议。Internet 网络采用的协议是TCP/IP协议,其全称是Transmission Control Protocol/Internet Protocol。Internet 依靠TCP/IP协议,在全球范围内实现了不同硬件结构、不同操作系统、不同网络系统间的互联。在Internet 网络上存在着数以亿计的主机,每台主机都用网络为其分配的 Internet 地址代表自己,这个地址就是I地址。到目前为止,I地址用4个字节,也就是32位的二进制数来表示,称为IPv4。为了便于使用,通常取用每个字节的十进制数,并且每个字节之间用圆点隔开来表示I地址,如192.168.1.1。现在人们正在试验使用16个字节来表示I地址,这就是IPv6,但IPv6还没有投入使用。
TCP/IP 模式是一种层次结构,共分为4层,分别为应用层、传输层、互联网层和网络层。各层实现特定的功能,提供特定的服务和访问接口,并具有相对的独立性

 TCP与UDP协议

在TCPAIP 协议栈中,有两个高级协议是网络应用程序编写者应该了解的,即传输控制协议(Transmission Control Protocol,TCP)与用户数据报协议(User Datagram Protocol, UDP)。

TCP 协议是一种以固接连线为基础的协议,它提供两台计算机间可靠的数据传送。TCP可以保证数据从一端送至连接的另一端时,能够确实送达,而且抵达的数据的排列顺序和送出时的顺序相同。因此,TCP协议适合可靠性要求比较高的场合。就像拨打电话,必须先拨号给对方,等两端确定连接后,相互才能听到对方说话,也知道对方回应的是什么。

HTTP、FTP 和Telnet 等都需要使用可靠的通信频道。例如,HTTP从某个URL读取数据时,如果收到的数据顺序与发送时不相同,可能就会出现一个混乱的HTML文件或是一些无效的信息。

UDP是无连接通信协议,不保证数据的可靠传输,但能够向若干个目标发送数据,或接收来自若干个源的数据。UDP以独立发送数据包的方式进行。这种方式就像邮递员送信给收信人,可以寄出很多信给同一个人,且每一封信都是相对独立的,各封信送达的顺序并不重要,收信人接收信件的顺序也不能保证与寄出信件的顺序相同。

UDP 协议适合于一些对数据准确性要求不高,但对传输速度和时效性要求非常高的网站,如网络聊天室、在线影片等。这是由于TCP协议在认证上存在额外耗费,可能使传输速度减慢,而UDP协议即使有一小部分数据包遗失或传送顺序有所不同,也不会严重危害该项通信。

端口与套接字

一般而言,一台计算机只有单一的连到网络的物理连接(Physical Connection),所有的数据都通过此连接对内、对外送达特定的计算机,这就是端口。网络程序设计中的端口(port)并非真实的物理存在,而是一个假想的连接装置。端口被规定为一个在0~65535的整数。HTTP服务一般使用80端口,FTP 服务使用21端口。假如一台计算机提供了HTTP、FTP等多种服务,那么客户机会通过不同的端口来确定连接到服务器的哪项服务上

通常,0~1023的端口数用于一些知名的网络服务和应用,用户的普通网络应用程序应该使用1024以上的端口数,以避免端口号与另一个应用或系统服务所用端口冲突。

网络程序中的套接字(Socket)用于将应用程序与端口连接起来。套接字是一个假想的连接装置,就像插座一样可连接电器与电线

 Java 将套接字抽象化为类,程序设计者只需创建Socket类对象,即可使用套接字。

TCP程序

TCP网络程序设计是指利用Socket 类编写通信程序。利用TCP协议进行通信的两个应用程序是有主次之分的,一个称为服务器程序,另一个称为客户机程序,两者的功能和编写方法大不一样。

  • 服务器程序创建一个 ServerSocket(服务器端套接字)对象,调用accept0方法等待客户机来连接
  • 客户端程序创建一个Socket对象,请求与服务器建立连接
  • 服务器接收客户机的连接请求,同时创建一个新的Socket 对象与客户建立连接。随后服务器继续等待新的请求
 InetAddress 类

java.net包中的InetAddress类是与IP地址相关的类,利用该类可以获取IP地址、主机地址等信息。

例题1

package 例题;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class 例题1 {

	public static void main(String[] args) {
		InetAddress ip;		
		try {
			ip = InetAddress.getLocalHost();
			String lo = ip.getHostName();
			String lp = ip.getHostAddress();
			System.out.println("本机名" + lo);
			System.out.println("本机IP地址" + lp);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}

	}

}

结果

ServerSocket 类
  • ServerSocker 类的构造方法通常会抛出1OException异常,具体有以下几种形式:
  • ServerSocket():创建非绑定服务器套接字。
  • ServerSocket(int port):创建绑定到特定端口的服务器套接字。
  • ServerSocket(int port, int backlog):利用指定的backlog创建服务器套接字,并将其绑定到指定的本地端口号上。
  • ServerSocket(int port, int backlog, InetAddress bindAddress):使用指定的端口、侦听backlog和要绑定到的本地IP地址创建服务器。这种情况适用于计算机上有多块网卡和多个I地址的情况,用户可以明确规定ServerSocket在哪块网卡或哪个IP地址上等待客户的连接请求

ServerSocket 类的常用方法

 TCP网络程序设计

例题2

客户端

package 例题;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.Socket;

import javax.swing.*;
import javax.swing.event.*;

public class 客户端 extends JFrame{
	private PrintWriter wr;
	Socket so;
	private JTextArea area = new JTextArea();
	private JTextField text = new JTextField();
	
	public 客户端() {
		setTitle("向服务器送数据");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Container con = getContentPane();
		JScrollPane scrollPane = new JScrollPane(area);
		getContentPane().add(scrollPane,BorderLayout.CENTER);
		con.add(text,"South");
		text.addActionListener(new ActionListener() {	
			
			public void actionPerformed(ActionEvent e) {
				wr.println(text.getText().trim());
				area.append(text.getText() + '\n');
				text.setText("");
			}
		});
	}
	
	private void connect() {
		area.append("尝试连接");
		try {
			so = new Socket("172.16.4.226",8888);
			wr = new PrintWriter(so.getOutputStream(),true);
			area.append("完成连接");
		}catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		客户端 k = new 客户端();
		k.setSize(200,200);
		k.setVisible(true);
		k.connect();

	}

}

结果

 

服务端

package 例题;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;

public class 例题2服务端 {

	private ServerSocket server;
	private Socket so;
	
	void start() {
		try {
			server = new ServerSocket(8888);
			System.out.println("服务器套接字已经创建成功");
			while(true) {
				System.out.println("等待客户机链接");
				so = server.accept();
				BufferedReader re = new BufferedReader(new InputStreamReader(so.getInputStream()));
				
				while(true) {
					String me = re.readLine();
					if("exit".equals(me)) {
						System.out.println("客户机退出");
						break;
					}
					System.out.println("客户机" + me);
				}
				re.close();
				so.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		例题2服务端 l = new 例题2服务端();
		l.start();

	}

}

结果 

UDP程序

 

基于 UDP通信的基本模式如下:

  • 将数据打包(称为数据包),然后将数据包发往目的地。
  • 接收别人发来的数据包,然后查看数据包。

发送数据包的步骤如下:

  1. 使用DatagramSocketO创建一个数据包套接字。
  2. 使用DatagramPacket(byte[] buf,int offset, int length,InetAddress address,int port)创建要发送的数据包。
  3. 使用DatagramSocket 类的sendO方法发送数据包。

接收数据包的步骤如下:

  1. 使用DatagramSocket(int port)创建数据包套接字,绑定到指定的端口。
  2.   使用 DatagramPacket(byte buf, int length)创建字节数组来接收数据包。
  3. 使用DatagramPacket 类的receive0方法接收UDP包。
DatagramPacket类

java.net 包的DatagramPacket 类用来表示数据包。DatagramPacket 类的构造方法如下:

DatagramPacket(byte[] buf, int length)
DatagramPacket(bytel] buf, int length, InetAddress address, int port)
第一种构造方法在创建DatagramPacket 对象时,指定了数据包的内存空间和大小。

第二种构造方法不仅指定了数据包的内存空间和大小,还指定了数据包的目标地址和端口
 

 

DatagramSocker类 
  • java.net 包中的()
  • DatagramSocket(int port)
  • DatagramSocket(int port, InetAddress addr)

第一种构造方法创建DatagramSocket对象,构造数据报套接字,并将其绑定到本地主机任何可用的端口上。

第二种构造方法创建DatagramSocket对象,创建数据报套接字,并将其绑定到本地主机的指定端口上。

第三种构造方法创建DatagramSocket对象,创建数据报套接字,并将其绑定到指定的端口和指定的本地地址上。第三种构造函数适用于有多块网卡和多个I地址的情况。

UDP网络程序设计

例题3

客户端

 
import java.io.IOException;
import java.net.*;
 
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"); // 实例化InetAddress,指定地址
			socket = new MulticastSocket(port); // 实例化多点广播套接字
			socket.setTimeToLive(1); // 指定发送范围是本地网络
			socket.joinGroup(iaddress); // 加入广播组
		} catch (IOException e) {
			e.printStackTrace(); // 输出异常信息
		}
	}
 
	public void 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); // 线程休眠
			} catch (IOException e) {
				e.printStackTrace(); 
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
 
	public static void main(String[] args) { 
		Notification w = new Notification();
		w.start(); // 启动线程
	}
}
//21.3

结果

服务端

 
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.net.*;
import javax.swing.*;
 
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(); // 创建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) { // 单击事件
		if (e.getSource() == inceBtn) { // 单击按钮ince触发的事件
			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);
	}
}

结果

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

排序算法之三:希尔排序

希尔排序基本思想 希尔排序法又称缩小增量法 希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组…

Vue3+ElementPlus:icon图标不显示(给表格字段里添加图标)

一、背景 在Vue3项目中,想在表格的字段中引入图标因为给字段做了触发提示,希望用户能够注意到这个功能,因此想加个图标提示一下用户,效果如下: 触发提示效果如下: (样式这里就不进行优化了&am…

【VS Code开发】使用Live Server搭建MENJA小游戏并发布至公网远程访问

文章目录 前言1. 编写MENJA小游戏2. 安装cpolar内网穿透3. 配置MENJA小游戏公网访问地址4. 实现公网访问MENJA小游戏5. 固定MENJA小游戏公网地址 前言 本篇教程,我们将通过VS Code实现远程开发MENJA小游戏,并通过cpolar内网穿透发布到公网,分…

【nodejs升级版本】win10 nodejs版本低升级版本流程

首先 网上说的n模块不支持window系统!!! window系统升级node只能到node官网下载window安装包来覆盖之前的node 升级步骤如下: 1,找到你node的安装路径,不知道的可以cmd命令行中输入这个命令就可以看到了…

Python:核心知识点整理大全13-笔记

目录 6.4.3 在字典中存储字典 6.5 小结 第7章 用户输入和while循环 7.1 函数 input()的工作原理 7.1.1 编写清晰的程序 7.1.2 使用 int()来获取数值输入 7.1.3 求模运算符 7.1.4 在 Python 2.7 中获取输入 7.2 while 循环简介 7.2.1 使用 while 循环 往期快速传送门…

jsonpath:使用Python处理JSON数据

使用Python处理JSON数据 25.1 JSON简介 25.1.1 什么是JSON JSON全称为JavaScript Object Notation,一般翻译为JS标记,是一种轻量级的数据交换格式。是基于ECMAScript的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清…

中国教师未来发展趋势

随着科技的进步和社会的发展,教师的发展趋势尤其引人关注。那么,教师未来的发展趋势又将是什么呢?” 引领未来的教育变革 在快速发展的信息化社会,教育行业正经历着前所未有的变革。中国教师将扮演着引领这场变革的重要角色。未来…

教培管理系统源码 培训管理系统源码

教培管理系统源码 培训管理系统源码 使用教培管理系统可以带来哪些好处: 1. 提高管理效率:教培管理系统可以自动化处理许多管理任务,如学生信息管理、课程管理、成绩管理等,从而减少人工干预,提高管理效率。 2. 提…

Nodejs后端+express框架

前言 基于vue3Node后台管理项目,补充nodejs和express相关知识。 文章目录 一,express 1.官网 Express - 基于 Node.js 平台的 web 应用开发框架 - Express中文文档 | Express中文网 2.安装 npm install express --save 二、MongoDB 特点 非关…

3D摄影棚布光:Set A Light 3D Studio

Set A Light 3D Studio是一款专业的灯光模拟软件,旨在帮助摄影师和电影制片人在电脑上进行虚拟灯光布置和场景模拟,以实现更加精准和高质量的拍摄效果。该软件提供了丰富的灯光和场景模型,支持灵活调整光源位置、强度、颜色和效果等参数&…

stm32学习:stm32f103c8t6+STM32CubeMX+st-link烧录+亮灯

准备材料: stm32f103c8t6开发板st-link烧录器安装stm32cubemx(官网下载就行)安装keil5(找找网上有很多破解软件,下载后破解)安装st-link驱动(下载入口STSW-LINK009 - 为Windows 7、Windows 8、Windows 10签署的ST-LIN…

基于深度学习的yolov7植物病虫害识别及防治系统

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介简介YOLOv7 系统特性工作流程 二、功能三、系统四. 总结 一项目简介 # YOLOv7植物病虫害识别及防治系统介绍 简介 该系统基于深度学习技术,采…

python+pytest接口自动化(13)-token关联登录

在PC端登录公司的后台管理系统或在手机上登录某个APP时,经常会发现登录成功后,返回参数中会包含token,它的值为一段较长的字符串,而后续去请求的请求头中都需要带上这个token作为参数,否则就提示需要先登录。 这其实就…

ArkUI Button组件

Button 1.声明button组件 Button(label?:ResourceStr) label是按钮上面显示的文字 如果不传入label 则需要在内部嵌套其他组件 内部嵌套其他组件 可以放入icon图标来构建自己想要的样式 按钮类型 按钮使用type(ButtonType.xxx)属性来设置,xxx的类型分为三种 1.…

想知道修改图片dpi会影响清晰度吗?点击这里找答案

很多人都对图片dpi分辨率有不少疑问,比如dpi对图片清晰的影响,还有哪些地方需要修改图片dpi?其实dpi是指每英寸墨点的数量。对同一张图像来说,一般使用300dpi比使用72dpi打印出来的效果要清晰很多 ,一般只有在打印照片或者上传证件…

pip指定优先从豆瓣源下载包

对于 Unix/macOS 系统,使用以下命令: pip config set global.index-url https://pypi.douban.com/simple/ 对于 Windows 系统,打开命令提示符或PowerShell,并使用相同的命令: pip config set global.index-url http…

Unity中实现ShaderToy卡通火(一)

文章目录 前言一、准备好我们的后处理基础脚本1、C#:2、Shader: 二、开始逐语句对ShaderToy进行转化1、首先,找到我们的主函数 mainImage2、其余的方法全部都是在 mainImage 函数中调用的方法3、替换后的代码(已经没报错了,都是效…

渲染技术在虚拟仿真中的应用

虚拟仿真(Virtual Reality)是一种仿真技术,它使用计算机生成一个虚拟世界,用户可以通过各种传感通道与这个虚拟世界进行自然的交互。虚拟仿真技术可以创建和体验虚拟世界,使用户可以像在真实世界中一样进行操作和体验。…

Python将字典列表导出为Excel文件的方法

将如下的字典列表内容导出为Excel表格文件形式: python将字典列表导出为Excel文件的方法,如下所示: 1、安装python官方Excel库------xlwt 直接在终端进行安装即可:pip install xlwt 安装完成后,在程序中引入xlwt的库…

ke14--10章-1数据库JDBC介绍

注册数据库(两种方式),获取连接,通过Connection对象获取Statement对象,使用Statement执行SQL语句。操作ResultSet结果集 ,回收数据库资源. 需要语句: 1Class.forName("DriverName");2Connection conn DriverManager.getConnection(String url, String user, String…