第21章总结 网络通信

news2024/11/20 13:20:02

21.1网络程序设计基础

21.1.1 局域网与互联网

为了实现两台计算机的通信,必须用一个网络线路连接两台计算机。如下图所示

21.1.2 网络协议
1.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层,分别为应用层、传输层、互联网层和网络层。各层实现特定的功能,提供特定的服务和

2. 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协议即使有一小部分数据包遗失或传送顺序有所不同,也不会严重危害该项通信。

21.1.3 端口与套接字

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

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

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

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

21.2 TCP程序

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

  • 例题21.1
  • import java.net.*;										//导出Java.net包
     
    public class Address {									//创建类
     
    	public static void main(String[] args) {
    		InetAddress ip;									//创建InetAddress对象
    		try {											//捕捉可能出现的异常
    			ip = InetAddress.getLocalHost();			//实例化对象
    			String locaIname = ip.getHostName();		//获取本机名
    			String localip = ip.getHostAddress();		//获取本机IP地址
    			System.out.println("本机名:"+locaIname);		//将本机名输出
    			System.out.println("本机名IP地址:"+localip);	//将本机IP地址输出
    		}catch(UnknownHostException e){
    			e.printStackTrace();						//输出异常信息
    		}
    		
    	}
     
    }//例题21.1

  • 21.2.2 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 类的常用方法如表21.2所示。
  • 21.2.3 TCP网络程序设计 

    例题

  • package 二十一章;
     
    import java.io.*;
    import java.net.*;
     
    public class MyServer {
        private ServerSocket server; // 服务器套接字
        private Socket socket; // 客户端套接字
     
        void start() {// 启动服务器
            try {
                server = new ServerSocket(8998); // 服务器启用8998端口
                System.out.println("服务器套接字已经创建成功");
                while (true) {
                    System.out.println("等待客户端的连接");
                    socket = server.accept(); // 服务器监听客户端连接
                    // 根据套接字字节流创建字符输入流
                    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    while (true) {// 循环接受信息
                        String message = reader.readLine();// 读取一行文本
                        if ("exit".equals(message)) {// 如果客户端发来的内容为“exit”
                            System.out.println("客户端退出");
                            break;// 停止接受信息
                        }
                        System.out.println("客户端:" + message);
                    }
                    reader.close(); // 关闭流
                    socket.close(); // 关闭套接字
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     
        public static void main(String[] args) {
            MyServer tcp = new MyServer();
            tcp.start(); // 启动服务器
        }
    }

  • 编写客户端程序,将用户在文本框中输入的信息发送至服务端,并将文本框中输入的信息显示再客户端的文本域中。

     
  •  
    package 二十一章;
     
    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    import java.net.Socket;
    import javax.swing.*;
     
    public class MyClient extends JFrame {
        private PrintWriter writer;// 根据套接字字节流创建的字符输出流
        Socket socket; // 客户端套接字
        private JTextArea area = new JTextArea();// 展示信息的文本域
        private JTextField text = new JTextField(); // 发送信息的文本框
     
        public MyClient() {
            setTitle("向服务器送数据");
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            Container c = getContentPane(); // 主容器
            JScrollPane scrollPane = new JScrollPane(area);// 滚动面板
            getContentPane().add(scrollPane, BorderLayout.CENTER);
            c.add(text, "South"); // 将文本框放在窗体的下部
            text.addActionListener(new ActionListener() {// 文本框触发回车事件
                public void actionPerformed(ActionEvent e) {
                    writer.println(text.getText().trim()); // 将文本框中的信息写入流
                    area.append(text.getText() + '\n'); // 将文本框中的信息显示在文本域中
                    text.setText(""); // 将文本框清空
                }
            });
        }
     
        private void connect() { // 连接服务器方法
            area.append("尝试连接\n"); // 文本域中提示信息
            try {
                socket = new Socket("127.0.0.1", 8998); // 连接本地计算机的8998端口
                writer = new PrintWriter(socket.getOutputStream(), true);
                area.append("完成连接\n");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     
        public static void main(String[] args) {
            MyClient clien = new MyClient();
            clien.setSize(200, 200); // 窗体大小
            clien.setVisible(true); // 显示窗体
            clien.connect(); // 连接服务器
        }
    }

  • 21.3 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包。

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

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

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

    21.3.2 DatagramSocker 类

    java.net 包中的()

    DatagramSocket(int port)
    DatagramSocket(int port, InetAddress addr)
            第一种构造方法创建DatagramSocket对象,构造数据报套接字,并将其绑定到本地主机任何可用的端口上。第二种构造方法创建DatagramSocket对象,创建数据报套接字,并将其绑定到本地主机的指定端口上。第三种构造方法创建DatagramSocket对象,创建数据报套接字,并将其绑定到指定的端口和指定的本地地址上。第三种构造函数适用于有多块网卡和多个I地址的情况。

    21.3.3 UDP网络程序设计
    例题21.3

    (1)广播主机程序不断地向外播放信息,代码

  •  
    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

  • (2)接收广播程序。单机“开始接收”按钮,系统开始接收主机播出的信息;单机“停止接收”按钮,系统停止接收广播主机播出的信息。代码如下:

  •  
    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);
    	}
    }

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

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

相关文章

如何利用人工智能+物联网技术实现自动化设备生产

随着科技的发展与行业竞争的日益激烈,制造业也逐渐走向智能化发展。制造业的改革是利用物联网技术和自动化设备,实现生产线的智能化和自适应生产,优化生产流程,提高生产效率和质量,为企业创造更大的价值。 方案概述 智…

计算目标检测和语义分割的PR

需求描述 实际工作中,相比于mAP项目更加关心的是特定阈值下的precision和recall结果;由于本次的GT中除了目标框之外还存在多边形标注,为此,计算IoU的方式从框与框之间变成了mask之间; 本文的代码适用于MMDetection下的…

wireshark过滤包小技巧

1、过滤包含某个字符串的数据包: 或者: 2、过滤包含某一连续十六进制的数据包: 或者: 3、过滤精确到位数位置 或者:

1-Tornado的介绍

1 tornado的介绍 **Tornado**是一个用Python编写的可扩展的、无阻塞的**Web应用程序框架**和**Web服务器**。 它是由FriendFeed开发使用的;该公司于2009年被Facebook收购,而Tornado很快就开源了龙卷风以其高性能着称。它的设计允许处理大量并发连接&…

实时动作识别学习笔记

目录 yowo v2 yowof 判断是在干什么,不能获取细节信息 yowo v2 https://github.com/yjh0410/YOWOv2/blob/master/README_CN.md ModelClipmAPFPSweightYOWOv2-Nano1612.640ckptYOWOv2-Tiny

2024年度AI投资策略报告:乘AI之风,破明日之浪

今天分享的AI系列深度研究报告:《2024年度AI投资策略报告:乘AI之风,破明日之浪》。 (报告出品方:万联证券) 报告共计:25页 1 需求复苏,政策指引热点驱动AI 赋能助推行业发展 1.1 …

【车载开发系列】Visio工具使用小技巧

【车载开发系列】Visio工具使用小技巧 【车载开发系列】Visio工具使用小技巧 【车载开发系列】Visio工具使用小技巧一. Word中编辑Visio技巧二. Word中插入visio图形的问题三. 总结 一. Word中编辑Visio技巧 本节主要介绍了Microsoft Word中编辑Visio图形的具体方法。 在 Word…

PyQt6 QTimeEdit时间控件

​锋哥原创的PyQt6视频教程: 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计39条视频,包括:2024版 PyQt6 Python桌面开发 视频教程(无废话…

Echarts图表title使用富文本

rich中有配置的话(如a)使用该样式,没有配置样式的话(如b)使用外层textstyle的样式,textstyle没有样式的话使用默认样式 const option1 {tooltip: {trigger: "item",},title: {text: ["{a|1…

线程及实现方式

一、线程 线程是一个基本的CPU执行单元,也是程序执行流的最小单位。引入线程之后,不仅是进程之间可以并发,进程内的各线程之间也可以并发,从而进一步提升了系统的并发度,使得一个进程内也可以并发处理各种任务&#x…

Linux就该这么学(第一天)

1.1 准备您的工具 所谓“工欲善其事,必先利其器”,在本章学习过程中,读者需要搭建出为今后练习而使用的红帽RHEL 7系统环境。您不需要为了练习实验而特意再购买一台新电脑,下文会讲解如何通过虚拟机软件来模拟出仿真系统。虚拟机…

使用 Tailwind CSS 完成导航栏效果

使用 Tailwind CSS 完成导航栏效果 本文将向您介绍如何使用 Tailwind CSS 创建一个漂亮的导航栏。通过逐步演示和示例代码,您将学习如何使用 Tailwind CSS 的类来设计和定制导航栏的样式。 准备工作 在开始之前,请确保已经安装了 Tailwind CSS。如果没…

异步回调模式

异步回调 所谓异步回调,本质上就是多线程中线程的通信,如今很多业务系统中,某个业务或者功能调用多个外部接口,通常这种调用就是异步的调用。如何得到这些异步调用的结果自然也就很重要了。 Callable、Future、FutureTask publi…

Python中利用遗传算法探索迷宫出路

更多资料获取 📚 个人网站:ipengtao.com 当处理迷宫问题时,遗传算法提供了一种创新的解决方案。本文将深入探讨如何运用Python和遗传算法来解决迷宫问题。迷宫问题是一个经典的寻路问题,寻找从起点到终点的最佳路径。遗传算法是一…

半导体划片机助力氧化铝陶瓷片切割:科技与工艺的完美结合

在当今半导体制造领域,氧化铝陶瓷片作为一种高性能、高可靠性的材料,被广泛应用于各种电子设备中。而半导体划片机的出现,则为氧化铝陶瓷片的切割提供了新的解决方案,实现了科技与工艺的完美结合。 氧化铝陶瓷片是一种以氧化铝为基…

基于ssm端游账号销售管理系统论文

摘 要 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对端游账号销售信息管理混乱,出错率高,信息安全…

单片机语言--C51语言的数据类型以及存储类型以及一些基本运算

C51语言 本文主要涉及C51语言的一些基本知识,比如C51语言的数据类型以及存储类型以及一些基本运算。 文章目录 C51语言一、 C51与标准C的比较二、 C51语言中的数据类型与存储类型2.1、C51的扩展数据类型2.2、数据存储类型 三、 C51的基本运算3.1 算术运算符3.2 逻辑…

使用Draw.io制作泳道图

使用Draw.io制作泳道图 一、横向泳道图1. 有标题泳道图2. 无标题泳道图3. 横纵向扩展泳道 二、纵向泳道图三、横纵交错地泳道图想做这样的图具体步骤1. 拖拽一个带标题的横向泳道图2. 拖拽一个带标题的单一图,并且把它放进Lane1中3. 其他注意 四、下载文件说明 一、…

ThinkPHP生活用品商城系统

有需要请加文章底部Q哦 可远程调试 ThinkPHP生活用品商城系统 一 介绍 此生活用品商城系统基于ThinkPHP框架开发,数据库mysql,前端bootstrap。系统分为用户和管理员。(附带配套设计文档) 技术栈:ThinkPHPmysqlbootstrapphpstudyvscode 二 …

SAP UI5 walkthrough step7 JSON Model

这个章节,帮助我们理解MVC架构中的M 我们将会在APP中新增一个输入框,并将输入的值绑定到model,然后将其作为描述,直接显示在输入框的右边 首先修改App.controllers.js webapp/controller/App.controller.js sap.ui.define([&…