第 19 章 网络编程

网络可以使不同物理位置上的计算机达到资源共享和通信的目的,在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();
}
}

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

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

相关文章

uview的u-calendar日历组件,当设置了 minDate配置项后,会导致第一次打开日历弹窗,不会精准的滚动到选中的日期(设置了默认日期都没用)

发现需要给month.vue文件里的getMonth方法加一个延时器,猜测是因为设置最小日期后,日历没渲染完毕的时候就已经开始获取节点信息了

C# Onnx Yolov8 Detect 印章 指纹捺印 检测

应用场景 检测文件中的印章和指纹捺印,用于判断文件是否合规(是否盖章,是否按印) 效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.…

Makefile应用

Makefile实例 在c.c里面&#xff0c;包含一个头文件c.h&#xff0c;在c.h里面定义一个宏&#xff0c;把这个宏打印出来。 c.c&#xff1a; #include <stdio.h> #include <c.h>void func_c() {printf("This is C %d\n", C); }c.h #define C 1然后上传…

跨国企业如何选择安全靠谱的跨国传输文件软件?

随着全球化的不断发展&#xff0c;跨国企业之间的合作变得越来越频繁。而在这种合作中&#xff0c;如何安全、可靠地将文件传输给合作伙伴或客户&#xff0c;成为了跨国企业必须面对的问题。 然而&#xff0c;跨国文件传输并不是一件容易的事情&#xff0c;由于网络物理条件的…

Mysql-库的操作

1.创建数据库 CREATE DATABASE [IF NOT EXISTS] name name后可以加 CHARACTER SET 或者是 charsetname COLLATE collation_name &#xff08;mysql数据库不区分大小写&#xff09; 说明&#xff1a; name表示想创建的库的名字大写的表示关键字 [] 是可选项 CHARACTER SET…

Linux调试器-gdb使用

程序的开发过程 debug和release ​ 程序的发布版本有debug和release版本&#xff0c;debug就是可被调试的&#xff08;debug环境下程序可以进行调试&#xff09;&#xff0c;release是发行版本&#xff0c;测试人员和用户使用的版本。Linux下我们编译代码时默认是release版本&…

苍穹外卖项目学习日记(13)

苍穹外卖项目学习日记(13) day10 Spring task cron表达式 导入spring task坐标&#xff08;spring-context已经存在&#xff09;&#xff0c;添加EnableScheduling注解 订单状态定时处理 新建task包&#xff0c;并且创建OrderTask定时类&#xff0c;添加处理超时订单和处…

网络运维Day12

文章目录 yum概述部署阿里镜像源yum基本使用 NFS网络文件系统NFS共享概述部署NFS服务端部署NFS客户端 Tomcat服务实验拓扑安装Tomcat启动服务客户端&#xff08;真机&#xff09;浏览访问页面测试 Tomcat虚拟主机NGINX服务web服务器对比NGINX简介实验拓扑虚拟机A源码编译安装NG…

ESP32-DHT11温湿度数据上传MQTT服务器

ESP32-DHT11温湿度数据上传MQTT服务器 简介ESP32DHT11 实验实验说明接线MQTT服务器建立连接添加订阅 ESP32驱动DHT11ESP32向MQTT服务器发送数据上传温湿度数据实验结果 简介 ESP32 点击图片购买 ESP32 系列模组集成 Wi-Fi、传统蓝牙和低功耗蓝牙功能&#xff0c;具有广泛的用途…

centos7系统离线安装tcpdump抓包软件、使用教程

tcpdump 是Linux系统下的一个强大的命令&#xff0c;可以将网络中传送的数据包完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤&#xff0c;并提供and、or、not等逻辑语句来帮助你去掉无用的信息。 本教程对tcpdump命令使用进行讲解说明&#xff0c;通…

对话金山云高级副总裁刘涛 | 做大模型公司的助力者

“ AIGC的应用化阶段将很快到来&#xff1b;AGI&#xff0c;已步入助手阶段。” 口述 | 刘涛 整理 | 梦婕&云舒 出品&#xff5c;极新 在10月的最后一天&#xff0c;极新有幸采访到了金山云高级副总裁刘涛。我们深入探讨了“云计算逐鹿 AIGC”的话题。作为中国公有云互…

Redhat Linux v8.2 实时内核环境配置及参数调优

BC-Linux V8.2 实时内核环境配置及参数调优 -------物理机 & 虚拟机 一、前言 本文档包含有关Redhat Linux for Real Time的基本安装和调试信息。许多行业和组织需要极高性能的计算&#xff0c;并且可能需要低且可预测的延迟&#xff0c;尤其是在金融和电信行业中。延迟&…

【MySQL】入门基础

文章目录 1 :peach:数据库基础:peach:1.1 :apple:什么是数据库:apple:1.2 :apple:主流数据库:apple:1.3 :apple:服务器/数据库/表关系:apple:1.4 :apple:MySQL架构:apple:1.5 :apple:SQL分类:apple:1.6 :apple:存储引擎:apple: 2 :peach:库的操作:peach:2.1 :apple:创建数据库:…

Xilinx MIPI4.3——bg<x>_pin<y>_nc

摘要&#xff1a;由于使用的需要&#xff0c;我要在一个bank上面使用4个MIPI D-PHY&#xff1b;如果pin的指定&#xff0c;跨了bytegroup就会出现bg<x>_pin<y>_nc信号&#xff0c;而且如果一个bit slice control被多个byte group 使用会发生报错&#xff1b;所以我…

202311.13 windows通过vscode ssh远程连接到Ubuntu 连接失败 waiting for server log

关闭VScode时没有关闭终端的Ubuntu进程&#xff1f; 导致重启后不能正常连接到Ubuntu了 Windows 系统自带的cmd终端通过ssh 可以连接 应该是vscode里对Ubuntu 的服务器端配置出了问题 参考&#xff1a;记录 VSCode ssh 连接远程服务器时出错及解决方法 在Windows 的vscode里面执…

关于MySQL优化的思考二【性能分析工具、优化原则】

在实际的工作中&#xff0c;我们不免需要对SQL预计进行分析和优化&#xff0c;今天我们就来一起看下相关内容&#xff1a; SQL性能分析 SQL优化原则 1 SQL性能分析 对SQL进行性能分析&#xff0c;主要有&#xff1a; 查看慢SQL 通过profile详情查看 explain执行计划 1.1…

大语言模型可以学习规则11.13

大型语言模型可以学习规则 摘要1 引言2 准备3 从假设到理论3.1 诱导阶段&#xff1a;规则生成和验证3.2 演绎阶段&#xff1a;使用规则库进行显式推理 4 实验评估实验装置4.2 数字推理 5 相关工作 摘要 当提示一些例子和中间步骤时&#xff0c;大型语言模型&#xff08;LLM&am…

Kotlin之控制语句和表达式

原文链接 Kotlin Controls and Expressions 有结果返回的是表达式&#xff0c;没有返回的称之为语句&#xff0c;语句最大的问题是它没有返回值&#xff0c;那么想要保存结果就必然会产生副作用&#xff0c;比如改变变量。很多时候这是不够方便的&#xff0c;并且在多线程条件…

基于springboot实现社区疫情防控平台管理系统项目【项目源码】

基于springboot实现社区疫情防控平台管理系统演示 SpringBoot框架 SpringBoot是一个全新开源的轻量级框架。基于Spring4.0设计&#xff0c;其不仅继承了Spring框架原来有的优秀特性&#xff0c;而且还通过简化配置文件来进一步简化了Spring应用的整个搭建以及开发过程。另外在…

语言大模型的预训练过程——从无尽数据到海量知识

从目前研究结果看&#xff0c;Transformer是足够强大的特征抽取器&#xff0c;通过预训练过程&#xff0c;Transformer学到了什么&#xff1f;知识是如何存取的&#xff1f;我们又如何修正错误知识&#xff1f;本文讲述这方面的研究进展。 1、求知&#xff1a;LLM学到了什么知…