当前位置: 首页 > news >正文

搭建Tomcat(一)---SocketServerSocket

目录

引入1

引入2--socket 

流程

Socket(应用程序之间的通讯保障)

网卡(计算机之间的通讯保障)

端口

端口号

实例

 client端

解析

server端

解析

相关方法

问题1:ServerSocket和Socket有什么关系?

ServerSocket

Socket

关系和作用总结

 问题2:ServerSocket和Socket的区别?

一、构造方法与参数

二、核心方法

三、通信过程


引入1

Tomcat是一个开源的Java Web服务器和Servlet容器,它遵循Servlet和JavaServer Pages(JSP)规范。Tomcat的架构主要包含两个核心组件:连接器(Connector)和容器(Container)。

那么Tomcat究竟是做什么的呢?---服务器开发

简而言之,一句话总结,tomcat就是一个用来承载项目的web容器

众所周知,我们自己创建的项目是不能随意访问的。

要想让网络能够随意访问这些项目,就要把它们丢进tomcat中。

上面将项目丢进tomcat的操作,就是实现其中配置的项目接受http请求

使用tomcat的过程,就是实现以下路径的转变:

经过上述简单概念,对tomcat的作用和概念有了简单的了解,接下来引入另一个重要概念:Socket。

引入2--socket 

如下的关系图是两个应用程序(或两台计算机)之间传输数据的构造图:

流程

简述不同计算机程序之间是如何互传信息的流程:

本台应用程序A输出一些数据信息,并且通过socket传输给本台操作系统对数据进行处理后变成由0和1组成的二进制数据流信号,进而被本台的网卡通过计算机网络(WiFi等)传输给另一台计算机的网卡接收,经另一台计算机的操作系统处理信息后,通过socket传输给应用程序B上展示。

以上就是一个完整的工作流程。

Socket(应用程序之间的通讯保障)

Socket(套接字)是网络通信中的一个抽象接口,它提供了进程间通信的端点。Socket允许同一台计算机或不同计算机上的应用程序通过网络进行通信,实现了跨网络的进程间通信。Socket不仅包含了IP地址和端口号等通信信息,还提供了数据传输和接收的接口。通过Socket,应用程序可以建立网络连接、发送和接收数据,实现网络通信的各种功能。

(每个Socket都对应一个来源,多个socket对应多个来源;Socket会一直保存来源线程,我们只需要通过Response直接返回到socket上即可!)

网卡(计算机之间的通讯保障)

网卡通常安装在计算机的主板插槽中,或者通过USB、PCIe等接口与计算机连接。它的主要功能是实现计算机与网络之间的数据交换,即将计算机内部的数据通过网络传输到外部,同时将外部网络的数据传输到计算机内部。

简而言之,网卡就是相互之间通过计算机网络接收和发送0101这种信息的一种物理硬件。

端口

端口是网络通信中的逻辑接口,用于区分不同的服务和应用进程。每个端口都有一个唯一的标识符,即端口号,用于标识特定的服务或应用进程。当计算机通过网络发送数据时,数据会被封装成数据包,并标记上目标端口号,以便接收端能够正确识别和处理。端口的作用在于确保数据能够准确地被发送到目标服务或应用进程,实现网络通信的精确性和可靠性。

端口号

  1. 作用:端口号用于唯一标识一个网络服务或应用程序。当计算机接收到一个数据包时,它会检查数据包中的目标端口号,并将数据包发送到监听该端口的服务或应用程序。
  2. 范围:端口号的范围通常是0到65535。其中,0到1023是系统保留端口,通常被用于常见的网络服务,如HTTP(80端口)、HTTPS(443端口)、FTP(21端口)等。这些端口通常被系统或管理员保留,不建议普通用户随意使用。1024到65535是用户端口或动态端口,可以由用户根据需要自由分配。

 如下,就是一个对端口号应用的例子:

通过端口号实现一台计算机上不同网络服务或应用程序的区分,以保证数据信息能够准确无误的传输。

实例

下面来实现客户端向服务端发送信息,以及服务端接收到并且输出的代码:

 client端

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;public class Client {public static void main(String[] args) throws IOException {//客户端只需要从本地IP地址向指定的端口去发送Socket socket=new Socket("127.0.0.1",8080);//打开输出流--准备传送数据OutputStream outputStream=socket.getOutputStream();//创建输出流类型的流数据类型参数PrintStream printStream=new PrintStream(outputStream);Scanner in=new Scanner(System.in);String x=in.nextLine();//获取一行的数据printStream.println(x);printStream.close();in.close();}
}

解析

接下来开始解析上述的代码:

Socket socket=new Socket("127.0.0.1",8080);

 "127.0.0.1"是本地IP,8080是一个端口号,这一条表示声明一个Socket对象,用于建立本地客户端与服务器之间的连接,通过8080端口。

 OutputStream outputStream=socket.getOutputStream();

通过Socket对象的getOutputStream()方法获取输出流;这个输出流用于向服务器发送数据 

 PrintStream printStream=new PrintStream(outputStream);

创建一个PrintStream对象,将OutputStream作为参数传入(将将 OutputStream 包装成 PrintStream

为什么使用PrintStream?

PrintStream提供了丰富的打印方法,使得向输出流写入数据变得更加方便,(如 print()println()printf() 等),这些方法可以自动将参数转换为字符串并写入到输出流中,同时,PrintStream还提供自动刷新功能,每次写入后都会自动调用 flush() 方法,确保数据被及时发送到输出流。

客户端的输出流一定要使用PrintStream吗?

  1. 如果数据是纯字节数据(如图像、音频文件等),那么直接使用 OutputStream 的 write() 方法就足够了,不需要将 OutputStream 包装成 PrintStream

  2. 如果数据是文本数据,并且需要格式化输出(如添加换行符、格式化数字等),那么使用 PrintStream 会更加便捷。

  3. 在客户端向服务器发送文本数据时,虽然可以直接使用 OutputStream 的 write(byte[] b, int off, int len) 方法来发送字符串的字节表示(通过字符串的 getBytes() 方法获取字节数组),但这样做需要手动处理字符串的编码和转换,而且不方便添加换行符等文本格式。因此,使用 PrintStream 可以简化这些操作。

Scanner in=new Scanner(System.in);
String x=in.nextLine();//获取一行的数据

键盘输出一行作为传送信息

 printStream.println(x);printStream.close();in.close();

使用PrintStream的println()方法将用户输入的字符串发送到服务器;其中println()方法会在字符串末尾自动添加换行符,并将其写入到输出流中。

完成这一切后,关闭scanner和printStream。

server端

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) throws IOException {run();}public static void run() throws IOException {ServerSocket serverSocket=new ServerSocket(8080); //0~65535监听接口while(true){//一直等待客户端连接(无限循环)//无限循环就意味着需要做出解除方法Socket socket= serverSocket.accept();//接收到client信息后,将获取的请求初始化给Socket(阻塞监听)//输出客户端给我们发来的程序InputStream inputStream=socket.getInputStream(); //打开输入流-接收输入的信息--并赋值给inputStreamint count=0;while(count==0){count= inputStream.available(); //获取可读出的字节数}byte[] bytes=new byte[count]; //开辟适合大小的byte数组inputStream.read(bytes);// 从输入流中读取数据到byte数组String context=new String(bytes);//将输入流转化为字符串输出System.out.println(context);}}
}

解析

接下来开始解析上述的代码:

ServerSocket serverSocket = new ServerSocket(8080);

创建一个监听端口8080的ServerSocket实例。端口号8080是任选的,但必须是0到65535之间的有效端口。

while (true)服务器持续运行,等待客户端连接。

Socket socket = serverSocket.accept();

accept方法会阻塞(暂停执行),直到一个客户端连接到服务器。一旦有连接,它就返回一个Socket实例,用于与该客户端通信。

 //输出客户端给我们发来的程序InputStream inputStream=socket.getInputStream(); //打开输入流-接收输入的信息--并赋值给inputStreamint count=0;while(count==0){count= inputStream.available(); //获取可读出的字节数}byte[] bytes=new byte[count]; //开辟适合大小的byte数组inputStream.read(bytes);// 从输入流中读取数据到byte数组String context=new String(bytes);//将输入流转化为字符串输出System.out.println(context);
  • InputStream inputStream = socket.getInputStream();:从客户端连接获取输入流,用于读取客户端发送的数据(创建输入流)。
  • int count = 0; while (count == 0) { count = inputStream.available(); }:这段代码读取输入流中可用的字节数。
  • byte[] bytes = new byte[count];:根据available()返回的字节数创建一个字节数组。
  • inputStream.read(bytes);:从输入流中读取数据到字节数组。
  • String context = new String(bytes);:将字节数组转换为字符串。方便下一步输出。
  • System.out.println(context);:在控制台上打印从客户端接收到的字符串。

运行1:

在client端借用socket输出流时(这个方法毋庸置疑,毕竟这两段代码的本质目的就是为了这个)

我在客户端输入“你好!”

将在服务器端接收到“你好!”

运行2

我在浏览器输入:

 

也能在服务端拦截到这个信息(这是因为服务器一直在拦截识别8080端口的信息,不管出自哪里,所用通路是一样的):

 

相关问题

通过上述的讲解和应用,罗列了以下问题:

问题1:ServerSocket和Socket有什么关系?

ServerSocket

ServerSocket 类位于 java.net 包中,它用于创建一个服务器端套接字,该套接字可以监听来自客户端的连接请求。服务器通过绑定到一个特定的端口来等待客户端的连接。一旦有客户端尝试连接到该端口,ServerSocket 就会接受这个连接,并返回一个新的 Socket 实例,该实例代表了服务器与客户端之间的通信链路。

ServerSocket 的主要作用包括:

  1. 监听端口:服务器绑定到一个特定的端口,等待客户端的连接请求。
  2. 接受连接:通过 accept() 方法阻塞等待,直到一个客户端连接请求到达。
  3. 返回通信链路:一旦连接建立,accept() 方法会返回一个 Socket 对象,用于后续的通信。

Socket

Socket 类同样位于 java.net 包中,它代表了一个客户端套接字,或者是一个服务器与客户端之间已经建立的通信链路(在服务器端,这个 Socket 对象是由 ServerSocket 的 accept() 方法返回的)。Socket 提供了输入流和输出流,用于在客户端和服务器之间发送和接收数据。

Socket 的主要作用包括:

  1. 建立连接:客户端通过 Socket 类的构造函数或 connect() 方法尝试连接到服务器。
  2. 获取输入/输出流:通过 getInputStream() 和 getOutputStream() 方法获取用于读取和写入数据的流。
  3. 通信:使用输入/输出流与服务器进行通信,发送和接收数据。
  4. 关闭连接:通过 close() 方法关闭与服务器的连接。

关系和作用总结

  • ServerSocket 用于服务器端,负责监听端口和接受客户端的连接请求。
  • Socket 用于客户端(或者服务器端与客户端之间的通信链路),负责建立连接、发送和接收数据。
  • 服务器端通过 ServerSocket 接受连接后,会返回一个 Socket 对象,该对象用于与客户端进行后续的通信。
  • 客户端通过 Socket 连接到服务器后,同样获得一个 Socket 对象(这个对象在客户端创建时就已经获得),用于与服务器进行通信。

 问题2:ServerSocket和Socket的区别?

一、构造方法与参数

  1. Socket

    • 常见的构造方法有:
      • Socket(String host, int port):创建一个Socket并连接到指定主机上的指定端口。
      • Socket(InetAddress address, int port):创建一个Socket并连接到指定IP地址和端口。
  2. ServerSocket

    • 常见的构造方法有:
      • ServerSocket(int port):创建一个绑定到指定端口的ServerSocket实例。
      • ServerSocket(int port, int backlog):创建一个绑定到指定端口的ServerSocket实例,并设置客户端连接请求队列的长度。
      • ServerSocket(int port, int backlog, InetAddress bindAddr):创建一个绑定到指定端口和IP地址的ServerSocket实例,并设置客户端连接请求队列的长度。

二、核心方法

  1. Socket

    • connect(SocketAddress endpoint):连接到服务器。
    • getInputStream():获取输入流,用于从服务器接收数据。
    • getOutputStream():获取输出流,用于向服务器发送数据。
  2. ServerSocket

    • accept():监听并接受客户端的连接。此方法会阻塞,直到有客户端连接为止。一旦连接建立,它会返回一个新的Socket对象,表示与客户端的连接。
    • getLocalPort():获取服务器套接字绑定的本地端口。
    • isClosed():检查ServerSocket是否已关闭。

三、通信过程

  1. Socket

    • 客户端创建一个Socket对象,指定服务器地址和端口。
    • 客户端通过Socket对象的输出流向服务器发送数据。
    • 客户端通过Socket对象的输入流接收服务器的响应。
  2. ServerSocket

    • 服务器创建一个ServerSocket对象,监听指定的端口。
    • 服务器调用ServerSocket对象的accept()方法,等待客户端的连接请求。
    • 一旦有客户端连接到服务器,ServerSocket会创建一个Socket对象与客户端进行通信。
    • 服务器通过Socket对象的输入流接收客户端发送的数据。
    • 服务器通过Socket对象的输出流发送响应给客户端。

相关文章:

搭建Tomcat(一)---SocketServerSocket

目录 引入1 引入2--socket 流程 Socket(应用程序之间的通讯保障) 网卡(计算机之间的通讯保障) 端口 端口号 实例 client端 解析 server端 解析 相关方法 问题1:ServerSocket和Socket有什么关系? ServerSocket Soc…...

ubuntu 使用 Times New Roman 字体在 Matplotlib 中绘图并调整字体大小

ubuntu 使用 Times New Roman 字体在 Matplotlib 中绘图并调整字体大小 文章目录 ubuntu 使用 Times New Roman 字体在 Matplotlib 中绘图并调整字体大小1. 安装 Times New Roman 字体验证字体是否安装成功 2. 在 Matplotlib 中加载 Times New Roman 字体3. 在 Matplotlib 中使…...

openGauss开源数据库实战二十三

文章目录 任务二十三 openGauss 参数管理任务目标实施步骤一、启动参数文件及参数类型1.参数值修改后必须重新启动数据库的参数2.参数值修改后只需要reload操作的参数 二、设置数据库级参数三、设置用户级参数四、设置会话级参数五、将参数设置为默认值 任务二十三 openGauss 参…...

MySQL 复合查询(重点)

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 MySQL 复合查询(重点) 收录于专栏[MySQL] 本专栏旨在分享学习MySQL的一点学习笔记,欢迎大家在评论区交流讨论💌 …...

ASP.NET |日常开发中连接Oracle数据库详解

ASP.NET |日常开发中连接Oracle数据库详解 前言一、安装和配置 Oracle 数据访问组件1.1 安装ODP.NET(Oracle Data Provider for.NET):1.2 引用相关程序集: 二、配置连接字符串2.1 连接字符串的基本组成部分&#xff1a…...

java_连接数据库的方法_后端处理_前端调用_打通整体思路

参考:14 尚上优选项目-平台管理端-权限管理模块-开发角色管理接口(上)_哔哩哔哩_bilibili 第一步. 定义数据 在数据库中定义好数据(如role表格),在java后端定义好对应的实体类(Role类&#xf…...

网络安全知识点

第一章 网络安全概述 1.2.1 网络安全概念P4 网络安全是指网络系统的硬件、软件及其系统中的数据受到保护,不因偶然的或恶意的原因而遭到破坏、更改、泄露,系统连续可靠正常地运行,网络服务不中断。 1.2.3 网络安全的种类P5 (1…...

pyfink1.20版本下实现消费kafka中数据并实时计算

1、环境 JDK版本:1.8.0_412python版本:3.10.6apache-flink版本:1.20.0flink版本:1.20kafka版本:kafka_2.12-3.1.1flink-sql-connector-kafka版本:3.3.0-1.202、执行python-flink脚本 从kafka的demo获取消…...

国产Tomcat东方通(TongWeb):Linux系统部署全攻略

国产Tomcat东方通(TongWeb):Linux系统部署全攻略 国产tomcat东方通tongweb在linux系统上部署全流程 [这里是图片001] 项目地址: https://gitcode.com/Resource-Bundle-Collection/fca68 项目介绍 在当前的软件开发和运维环境中&#xff0c…...

bilstm -crf 的torch官方的教程 不支持 batchsize 。。。。有更效率更高的方案吗

根据您的需求,您正在寻找一个支持批量处理(batch size)的BiLSTM-CRF模型的PyTorch教程。以下是一些资源,它们提供了更高效的解决方案,包括批量处理的支持: 1. **a-PyTorch-Tutorial-to-Sequence-Labeling*…...

Python面试常见问题及答案6

一、基础部分 问题1: 在Python中,如何将字符串转换为整数?如果字符串不是合法的数字字符串会怎样? 答案: 在Python中,可以使用int()函数将字符串转换为整数。如果字符串是合法的数字字符串,转换…...

代码随想录算法训练营第三天 | 链表理论基础 | 203.移除链表元素

感觉上是可以轻松完成的,因为对链接的结构,元素的删除过程心里明镜似的 实际上四处跑气 结构体的初始化好像完全忘掉了,用malloc折腾半天,忘记了用new,真想扇自己嘴巴子到飞起删除后写一个函数,把链表打印…...

1. 机器学习基本知识(5)——练习题(1)

1.7 🐦‍🔥练习题(本章重点回顾与总结) 0.回答格式约定: 对于书本内容的回答,将优先寻找书本内容作为答案进行回答。 书本内容回答完毕后,将对问题进行补充回答,上面分割线作为两个…...

vue 自定义组件image 和 input

本章主要是介绍自定义的组件:WInput:这是一个验证码输入框,自动校验,输入完成回调等;WImage:这是一个图片展示组件,集成了缩放,移动等操作。 目录 一、安装 二、引入组件 三、使用…...

系列3:基于Centos-8.6 Kubernetes使用nfs挂载pod的应用日志文件

每日禅语 古代,一位官员被革职遣返,心中苦闷无处排解,便来到一位禅师的法堂。禅师静静地听完了此人的倾诉,将他带入自己的禅房之中。禅师指着桌上的一瓶水,微笑着对官员说:​“你看这瓶水,它已经…...

Jfinal项目整合Redis

1、引入相关依赖 <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version> </dependency><depen…...

在Ubuntu服务器上备份文件到自己的百度网盘

文章目录 概述安装bypy同步文件定时任务脚本 概述 之前自购了一台阿里云服务器&#xff0c;系统镜像为Ubuntu 22.04&#xff0c; 并且搭建了LNMP开发环境&#xff08;可以参考&#xff1a;《Ubuntu搭建PHP开发环境操作步骤(保姆级教程)》&#xff09;。由于项目运行中会产生附…...

Unity 模板测试透视效果(URP)

可以实现笼中窥梦和PicoVR中通过VST局部透视效果。 使用到的Shader: Shader "Unlit/StencilShader" {Properties{[IntRange]_Index("Stencil Index",Range(0,255))0}SubShader{Tags{"RenderType""Opaque""Queue""Geo…...

《计算机视觉证书:开启职业发展新航道》

一、引言 在当今科技飞速发展的时代&#xff0c;计算机视觉技术正以惊人的速度改变着我们的生活和工作方式。从智能手机的人脸识别解锁到自动驾驶汽车的环境感知&#xff0c;计算机视觉技术的应用无处不在。而计算机视觉证书作为这一领域的专业认证&#xff0c;其作用愈发凸显…...

.NET6 WebApi第1讲:VSCode开发.NET项目、区别.NET5框架【两个框架启动流程详解】

一、使用VSCode开发.NET项目 1、创建文件夹&#xff0c;使用VSCode打开 2、安装扩展工具 1>C# 2>安装NuGet包管理工具&#xff0c;外部dll包依靠它来加载 法1》&#xff1a;NuGet Gallery&#xff0c;注意要启动科学的工具 法2》NuGet Package Manager GUl&#xff0c…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...