第 19 章 网络编程

news2024/11/26 16:34:47

网络可以使不同物理位置上的计算机达到资源共享和通信的目的,在Java中也提供了专门的网络开发程序包--java.net,以方便开发者进行网络程序的开发,本章将讲解TCP与UDP程序开发

19.1 网络编程简介

        将地理位置不同的、具有独立功能的多台计算机连接在一起就形成了网络,网络形成后网络中的各台主机就需要具有通信功能,所以才为网络创造一系列的通信协议。在整个通信过程中往往会分为两种端点:服务端与客户端,所以围绕着服务端和客户端的程序开发就有了两种模式。
        C/S(Client/Server):要开发两套程序,一套是服务器端;另一套是与之对应的客户端,但是这种模式在进行维护的时候,需要维护两套程序,而且客户端的程序更新也必须及时,此类程序安全性能好。
        B/S(Browser/Server):只需针对服务器端开发一整套程序,客户端使用浏览器进行访问。这种程序在日后进行程序维护的时候只需维护服务器端即可,客户端不需要做任何修改。此类程序使用公共端口,包括公共协议,所以安全性很差。
本章重点讲解C/S接口的程序的两种实现:TCP模型和UDP模型
提问:HTTP是什么
在日常使用中,很多时候使用HTTP进行访问,HTTP通信和TCP通信有什么联系。
回答:TCP是HTTP通信的基础协议
        实际上HTTP通信也是基于TCP协议的一种应用,是在TCP协议基础上追加了一些HTTP标准后形成的HTTP通信。HTTP通信不仅仅在B/S结构上被广泛应用,同时在一些分布式开发中也使用较为广泛。JavaWeb开发(JSP、Servlet、Ajax等)就是java针对HTTP协议提供的开发支持。
        顺带提醒的是,Java只提供最为核心的网络开发支持,而如果真的要想开发一个具有稳定通信能力的网络程序是,开发者必须精通各种通信协议。为了简化此类开发,开源世界提供了一个Netty开发框架,可以帮助开发者轻松实现各种常见的TCP、UDP、HTTP、WebSocket通信协议。

19.2 Echo程序模型

在TCP编程模型中,Echo是一个经典的程序案例,Echo程序模型的基本思想在于,客户端通过键盘输入一个信息,把此信息发送给服务器端后,服务器端会将此信息反馈给客户端进行显示,本操作主要通过java.net包的两个类实现。
        ServerSocket类:封装TCP协议类,工作在服务器端,常用的方法如表
        Socket类:封装TCP协议的操作类,每一个Socket对象都表示一个客户端

Echo通信模型的实现需要通过ServerSocket类在服务器端定义数据监听端口,在没有客户端连接时将一直处于等待连接状态。每一个客户端连接到服务器端后都通过Socket实例描述,通过Socket可以获取客户端和输出端的实例,这样就可以实现I/O通信
        范例:定义Echo服务器端

package cn.mldn.demo;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.util.Scanner;
public class EchoServer
{
public static void main(String[]args)throws Exception
{
ServerSocket server=new ServerSocket(9999);//设置服务器监听端口
System.out.println("等待客户端连接。。。。。。。。。");
Socket client=server.accept();
//首先需要先接收客户端发送来的信息,而后才可以将信息处理后发送给客户端
Scanner scan=new Scanner(client.getInputStream());//客户端输入流
scan.useDelimiter("\n");//设置分隔符
PrintStream out=new PrintStream(client.getOutputStream());//客户端输出流
boolean flag=true;
while(flag)
{
if(scan.hasNext())
{
String val=scan.next().trim();//接收数据内容
if("byebye".equalsIgnoreCase(val))
{
out.println("byebyebye");
flag=false;
}else
{
out.println("echo"+val);
}
}
}

scan.close();
out.close();
client.close();
server.close();
}
}

本程序在主线程实例化了一个ServerSocket类对象,并且设置了在本季的9999端口上进行监听,当有客户端连接到服务器端后(accept()方法在客户端连接前会一直泽色程序运行),会获取客户端Socket的输入流和输出流,进行数据的接收与回应处理。

提示:使用telnet命令测试

在Windows、Linux等系统中都会提供一个telnet的测试命令,进行服务器端的使用测试,开发者只需要输入telnet localhost9999命令即可直接与服务器端程序连接。如果在Windows系统中此命令默认不开启,则开发者选择启用或关闭Windows功能。服务端的主要功能是进行客户端发送数据的回显处理,客户端需要实现键盘数据的输入并且通过Socket实例实现数据的发送与回应处理。

范例:编写客户端程序

package cn.mldn.demo;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class EchiClient
{
private static finale BufferedReader KEYBORAD_INPUT=new BufferedReader(new InputStreamReader(System.in));
public static String getString(String prompt)throws Exception
{
//键盘信息的输入
System.out.print(prompt);
String str=KEYBOARD_INPUT.readLine();
return str;
}
public static void main(String[]args)throws Exception
{
Socket client=new Socket("localhost",9999);//定义服务器端的连接信息
//现在的客户端需要有输入与输出的操作支持,所以依然要准备出Scanner和PrintWriter
Scanner scan=new Scanner(client.getInputStream());//接收服务器端输入内容
scan.useDelimiter("\n");
PrintStream out=new PrintStream(client.getOutputStream());//向服务器端发送内容
boolean flag=true;//循环标记
while(flag)
{
String input=getString("请输入要发送的内容").trim();//获取键盘输入数据
out.println(input);//加换行
if(scan.hasNext())
{
System.out.println(scan.next());//输出回应消息
}
if("byebye").equlasIgnoreCase(input){flag=false;}
}
}

scan.close();
out.close();
client.close();
}

19.3 BIO处理模型

此时的Echo模型是基于单线程(主线程)的处理机制实现的网络通信,这样会造成一个问题,在同一段时间内只允许有一个客户端连接到服务器端并进行通信处理,并且当次客户端退出后服务器端也会随之关闭,所以为了提升服务器段的处理性能,就可以利用多线程来处理多个客户端的通信需求

根据上图可以发现,在服务器端中的每一个ServerSocket需要连接多个Socket,同时可以将每一个客户端的Socket实例封装在一个线程中,这样一个服务器端就可以同时处理多个客户端请求。

范例:修改服务器端实现

package cn.mldn.demo;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.util.Scanner;
public class EchoServer
{
private static vlass ClientThread implements Runnable
{
private Socket client=null;//客户端Socket
private Scanner scan=null;//输入流
private PrintStream out=null;//输出流
private boolean flag=true;
public ClientThread(Socket client)throws Exception
{
this.client=client;//保存Socket
this.scan=new Scanner(client.getInputStream());//输入流
this.scan.useDelimiter("\n");//设置分隔符
this.out=new PrintStream(client.getOutputStream());//输出流
}

@Override 
public void run()
{
while(this.flag)
{
if(scan.hasNext())
{
String val=scan.next().trim();
if("byebye".equalsIgnoreCase(val))
{
out.println("byebyebye");
this.flag=false;
}else
{
out.println("【ECHO】"+val);
}
}
}
scan.close();
out.close();
client.close();
}
}
}

public static void main(String[]args)throws Exception
{
ServerSocket server=new ServerSocket(9999);//设置服务监听端口
System.out.println("等待客户端连接......");
boolean flag=true;
while(flag)
{
Socket client=server.accept();//有客户端连接
new Thread(new ClientThread(client)).start();
}
server.close();
}

本程序服务器端将采用玄幻的形式实现多个Socket客户端的连接,并且将每一个接受到的Socket实例封装到独立的线程中进行独立的Echo回应处理。

提示:本模型属于BIO模型
        在本程序中虽然是用了多线程修改了服务器端处理模式,但是在程序开发中并没有对服务器端可用线程数量进行限制,这也就意味着如果并发客户端访问量增加,则服务器端将会出现严重的性能问题。所以JDK1.4以前就必须对县城熟练进行有效控制,需要追加客户端等待了解机制才可以正常使用,这种模式称为BIO(Blocking IO,阻塞IO)模式。

19.4 UDP程序

TCP的所有操作都必须建立可靠的连接才可以通信,但是这种做法肯定会浪费大量的系统性能,为了减少这种开销,在网络中又提供了另外一种传输协议--UDP(不可靠连接),即利用数据报的形式进行数据发送,由于没有建立可靠连接,此时接收端可能处于关闭状态,所以利用UDP发送的数据,客户端不一定接收到。在Java中使用DatagramPacket类和DatagramSocket类,完成UDP程序的开发
提示:关于UDP开发中服务器端和客户端的解释
        使用UDP开发的网络程序,类似于平常使用手机,手机实际上相当于一个客户端,如果现在手机要是想正常收信息,则手机肯定要先打开才行。

范例:实现一个UDP客户端进行信息接收

在进行UDP客户端编写时需要设置一个客户端的监听端口,结束到的数据信息可以利用DatagramPacket类对象进行接收,这样在客户端打开的情况下会自动接收到服务器端发送来的消息。

package cn.mldn.demo;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPClient
{
public static void main(String[]args)throws Exception
{
DatagramSocket client=new DatagramSocket(9999);//接收数据信息
byte data[]=new byte[1024];//保存接收数据
DatagramPacket packet=new DatagramPacket(data,data.length);//创建数据报
System.out.println("客户端等待接收发送的消息");
client.receive(packet);//接收消息内容
System.out.println("接受到的信息内容为"+new String(data,0,packet,getLength()));
client.close();
}
}

在进行UDP客户端编写时需要设置一个客户端的监听端口,接收到的数据信息可以利用DatagramPacket类对象进行接收,这样在客户端打开的情况下会自动接收到服务器端发来的信息。

范例:编写一个UDP服务器端程序发送数据报

package cn.mldn.demo;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPServer
{
public static void main(String[]args)throws Exception
{
DatagramSocket server=new DatagramSocket(9000);
String str="AAA";
DatagramPacket packet=new DatagramPacket(str.getBytes(),0,str.length(),InetAdress.getByName(localhost),9999);
server.send(packet);
server.close();
}
}

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

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

相关文章

Leetcode-110 平衡二叉树

递归实现 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

优选算法精品解析

1.双指针(前后/左右双指针) 1.1 283.移动零 快排双指针的核心算法 左边所有数 < tmp,右边所有数 > tmp,以tmp这个数为标准 1.2 1089.复习零 如果一对双指针从左向右不行,那么就从右向左,换一个方向 1.3 202.快乐数 双指针中的快慢指针: slow1,fast2 1.4 11.最多盛水的…

如何使用免费的 Vecteezy 旅行视频

网址&#xff1a;https://www.vecteezy.com/ Vecteezy 是一个提供免费和付费矢量图形、模板、视频和其他创意资源的网站。该网站拥有大量旅行视频&#xff0c;可用于各种目的&#xff0c;例如个人使用、商业用途或教育用途。 要下载 Vecteezy 的免费旅行视频&#xff0c;请按…

类和对象(4):Date类.运算符重载 1

一、赋值运算符重载 1.1 运算符重载 运算符重载是具有特殊函数名的函数&#xff0c;函数名字为&#xff1a;关键词operator需要重载的运算符符号。 不能重载C/C中未出现的符号&#xff0c;如&#xff1a;operator。重载操作符必须有一个类类型参数。不能改变用于内置类型运算…

详细推导MOSFET的跨导、小信号模型、输出阻抗、本征增益

目录 前言 什么是跨导 什么是小信号模型 什么是输入阻抗和输出阻抗 什么是MOS管的输出阻抗 什么是MOS管的本征增益 共源极放大电路的输入和输出阻抗 一些其它MOS拓扑电路的增益 负载为恒流源 负载为二极管 前言 相信很多人在学习集成电路领域的时候 都对MOS管的…

HTML设置标签栏的图标

添加此图标最简单的方法无需修改内容&#xff0c;只需按以下步骤操作即可&#xff1a; 1.准备一个 ico 格式的图标 2.将该图标命名为 favicon.ico 3.将图标文件置于index.html同级目录即可 为什么我的没有变化&#xff1f; 答曰&#xff1a;ShiftF5强制刷新一下网页就行了

C#,数值计算——多项式计算,Poly的计算方法与源程序

1 文本格式 using System; using System.Text; namespace Legalsoft.Truffer { /// <summary> /// operations on polynomials /// </summary> public class Poly { /// <summary> /// polynomial c[0]c[1]xc[2]x^2 ..…

西门子精智屏数据记录U盘插拔问题总结

西门子精智屏数据记录U盘插拔问题总结 注意: 数据记录过程中不允许带电插拔 U 盘! 数据记录的相关功能可参考以下链接中的内容: TIA博途wincc V16 如何进行变量周期归档?

Java 之集合框架的详细介绍

文章目录 总的介绍1. **Collection 接口**2. **List 接口**3. **Set 接口**4. **Map 接口**5. **HashMap、LinkedHashMap、TreeMap**6. **Queue 接口**7. **Deque 接口** ArrayList 类1. **创建 ArrayList&#xff1a;**2. **添加元素&#xff1a;**3. **插入元素&#xff1a;*…

centos利用find提权反弹shell

需要说明的是利用find命令进行提权的方式已经不存在了&#xff0c;因为Linux默认不会为find命令授予suid权限&#xff0c;这里只是刻意的制造出了一种存在提权的环境 首先我们先介绍一下find命令&#xff0c;find命令主要用来在Linux中查找文件使用&#xff0c;它可以进行最基础…

Brute Force

Brute Force "Brute Force"&#xff08;暴力破解&#xff09;指的是一种通过尝试所有可能的组合来获取访问、解密或破解信息的攻击方法。这种攻击方法通常是基于暴力和不断尝试的&#xff0c;不依赖漏洞或弱点。通常用于破解密码、破坏系统或获取未经授权的访问权限…

如何在thingsboard的规则链中对一个遥测属性进行求平均值

背景 有这样一个需求,一个温度传感器每5秒,上传一次数据。要求算出该设备2分钟内的平均温度,如果超过某个值,则发送告警邮件。 具体操作实现 下面在规则链中实现求平均值。 使用的节点是 配置如下 必填 Timeseries keys,是要求的平均值的属性名。 我这里求的是四个…

AI大模型低成本快速定制秘诀:RAG和向量数据库

文章目录 1. 前言2. RAG和向量数据库3. 论坛日程4. 购票方式 1. 前言 当今人工智能领域&#xff0c;最受关注的毋庸置疑是大模型。然而&#xff0c;高昂的训练成本、漫长的训练时间等都成为了制约大多数企业入局大模型的关键瓶颈。 这种背景下&#xff0c;向量数据库凭借其独特…

【Python Opencv】Opencv画图形

文章目录 前言一、画图形1.1 画线1.2 画矩形1.3 画圆1.4 画椭圆1.5 添加文本 总结 前言 在计算机视觉和图像处理中&#xff0c;OpenCV不仅可以处理图像和视频&#xff0c;还提供了一组功能强大的工具&#xff0c;用于在图像上绘制各种形状和图形。这些功能使得我们能够在图像上…

arm2 day6

串口实现单个字符的收发 main.c uart4.c uart4.h

107.am40刷机折腾记3-firefly镜像的烧写

1. 平台&#xff1a; rk3399 am40 4g32g 2. 内核&#xff1a;firefly的内核&#xff08;整体镜像&#xff09; 3. 交叉编译工具 &#xff1a;暂时不编译 4. 宿主机&#xff1a;ubuntu18.04 5. 需要的素材和资料&#xff1a;boot-am40-20231113.img(自编译) 准备的情况&a…

数据库表的设计——范式

目录 1. 设计数据表需要注意的点 2. 范式 2.1 范式简介 2.2 范式有哪些&#xff1f; 2.3 第一范式(1NF) 2.4 第二范式(2NF) 2.5 第三范式(3NF) 2.6 小结 1. 设计数据表需要注意的点 &#xff08;1&#xff09;首先要考虑设计这张表的用途&#xff0c;这张表都要存放什…

Docker的安装配置与使用

1、docker安装与启动 首先你要保证虚拟机所在的盘要有至少20G的空间&#xff0c;因为docker开容器很吃空间的&#xff0c;其次是已经安装了yum依赖 yum install -y epel-release yum install docker-io # 安装docker配置文件 /etc/sysconfig/docker chkconfig docker on # 加…

数据库 并发控制

多用户数据库系统&#xff1a;允许多个用户同时使用同一个数据库的数据库系统 交叉并发方式&#xff1a;在单处理机系统中&#xff0c;事务的并行执行实际上是这些并行事务的并行操作轮流交叉运行 同时并发方式&#xff1a;在多处理机系统中&#xff0c;每个处理机可以运行一个…

手机厂商参与“百模大战”,vivo发布蓝心大模型

在2023 vivo开发者大会上&#xff0c;vivo发布自研通用大模型矩阵——蓝心大模型&#xff0c;其中包含十亿、百亿、千亿三个参数量级的5款自研大模型&#xff0c;其中&#xff0c;10亿量级模型是主要面向端侧场景打造的专业文本大模型&#xff0c;具备本地化的文本总结、摘要等…