搭建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对象的输出流发送响应给客户端。

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

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

相关文章

爬虫学习案例5

爬取b站一个视频 罗翔老师某一个视频很刑 单个完整代码: 安装依赖库 pip install lxml requests import osimport requests import re from lxml import etree import json # 格式化展开输出 from pprint import pprint # 导入进程模块 import subprocess head…

【深度学习】 零基础介绍卷积神经网络(CNN)

零基础介绍 卷积神经网络(CNN,Convolutional Neural Network)是深度学习中的一种神经网络,特别擅长处理图像和视频等有空间结构的数据。 假设我们在做一个“照片分类”的任务,比如判断一张照片中是猫还是狗。下面用一…

【计算机组成原理】实验二:通用寄存器单元实验

实验二:通用寄存器单元实验 一、实验目的 了解通用寄存器的组成和硬件电路,利用通用寄存器实现数据的置数、左移、右移等功能。 二、实验内容 数据输入通用寄存器 寄存器内容无进位位左移实验 寄存器内容无进位位右移实验 三、实验步骤和结果 实…

4G模块详解

在之前的教程中,无线通信技术我们学习了蓝牙和 WiFi,今天我们要来学习 4G。 4G 模块在距离上有个突破,它不像蓝牙短距离,也不像 WiFi 只能在局域网,4G 模块可使用户无论在哪,只要有 4G 网络信号覆盖&#…

Visual Studio 使用 GitHub Copilot 聊天

🎀🎀🎀【AI辅助编程系列】🎀🎀🎀 Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码Visual Studio 安装和管理 GitHub CopilotVisual Studio 使用 GitHub Copilot 扩展Visual Studio 使用 GitHu…

TimerPickerDialog组件的用法

文章目录 1 概念介绍2 使用方法3 示例代码我们在上一章回中介绍了Snackbar Widget相关的内容,本章回中将介绍TimePickerDialog Widget.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在这里说的TimePickerDialog是一种弹出窗口,只不过窗口的内容固定显示为时间,它主…

Linux高并发服务器开发 第四天(wc/whoami命令 权限修改chmod 添加/删除用户(组) 切换用户 修改文件所有者/所属组 查找/过滤)

目录 1.wc和whoami命令 1.1wc命令 1.2whoami命令 2.用户权限/用户/用户组 2.1修改文件权限chmod 2.1.1文字设定法 2.1.2数字设定法 2.2添加删除新用户和新用户组 2.3切换用户 2.4修改文件所有者和所属组 2.4.1修改所有者 2.4.2修改所属组 3.查找和过滤 3.1find—…

微服务架构导学

一. 什么是微服务 微服务是一个软件架构风格,将一个大型的项目拆分成多个小项目,每个项目都被称为一个微服务,通过多个微服务共同组成一个大的项目。 二. 单体架构和微服务架构 单体架构 将整个项目的功能、模块全部堆积在一个项目中 优点&am…

【kubernetes】kubectl get nodes报NotReady

目录 1. 说明2. 问题描述3. kube-flannel.yml 1. 说明 1.这里k8s的版本是v1.17.4。2.若kube-flannel.yml中的镜像拉取不下来,可以下载本文章的文件资源,手动docker load -i ***.tar的方式。3.v1.17.4的kube-flannel.yml参考下面代码。4.通过kubectl get…

web实操7——ServletContext

概念 和服务器通信 功能 解释说明: mime:互联网中一种文件的类型,可以用servletContext对象来获取。 域对象:用来共享数据,里面有一些get,set,removeAttribute,只要搞清楚ServletContext对象的域的范围是什么 如何…

LLMC:大语言模型压缩工具的开发实践

关注:青稞AI,学习最新AI技术 青稞Talk主页:qingkelab.github.io/talks 大模型的进步,正推动我们向通用人工智能迈进,然而庞大的计算和显存需求限制了其广泛应用。模型量化作为一种压缩技术,虽然可以用来加速…

舌头分割数据集labelme格式2557张1类别

数据集格式:labelme格式(不包含mask文件,仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数):2557 标注数量(json文件个数):2557 标注类别数:1 标注类别名称:["tongue"] 每个类别标注的框数&#xff1…

测试工程师八股文03|Python编程题

一、题目 1、合并两个数组 class Solution:def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:nums1[m:] nums2nums1.sort()2、判断链表中是否有环 class Solution:def hasCycle(self, head: ListNode) -> bool:seen set()while head:if…

MyBatis-Plus 基础

教程 视频教程:https://www.bilibili.com/video/BV1Xu411A7tL 详细文档:https://b11et3un53m.feishu.cn/wiki/PsyawI04ei2FQykqfcPcmd7Dnsc 常见注解 MybatisPlus就是根据PO实体的信息来推断出表的信息,从而生成SQL的。默认情况下&#xf…

VMware Workstation Pro 17 下载 以及 安装 Ubuntu 20.04.6 Ubuntu 启用 root 登录

1、个人免费版本 VMware Workstation Pro 17 下载链接怎么找?直接咕咕 VMware 找到如下链接。链接如下:Workstation 和 Fusion 对个人使用完全免费,企业许可转向订阅 - VMware 中文博客 点进去链接之后你会看到如下,注意安装之后仍…

深度学习——激活函数、损失函数、优化器

深度学习——激活函数、损失函数、优化器 1、激活函数1.1、一些常见的激活函数1.1.1、sigmoid1.1.2、softmax1.1.3、tanh1.1.4、ReLU1.1.5、Leaky ReLU1.1.6、PReLU1.1.7、GeLU1.1.8、ELU 1.2、激活函数的特点1.2.1、非线性1.2.2、几乎处处可微1.2.3、计算简单1.2.4、非饱和性1…

智慧政务数据中台建设及运营解决方案

数据中台:政府数字化转型的引擎 数据中台作为政府数字化转型的核心驱动力,起源于美军的作战体系,强调高效、灵活与强大。它不仅促进了政府决策的科学性,还推动了政府服务的精细化与智能化。 数据中台的应用场景:数字…

计算机毕设-基于springboot的社区居民诊疗健康管理系统的设计与实现(附源码+lw+ppt+开题报告)

博主介绍:✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围:Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…

day11 性能测试(4)——Jmeter使用(黑马的完结,课程不全)直连数据库+逻辑控制器+定时器

【没有所谓的运气🍬,只有绝对的努力✊】 目录 1、复习 1.1 断言(3种) 1.2 关联(3种) 1.3 录制脚本 2、Jmeter直连数据库 2.1 直连数据库——使用场景 2.2 直连数据库——操作步骤 2.2.1 案例1&…

React的状态管理库-Redux

核心思想:单一数据源、状态是只读的、以及使用纯函数更新状态。 组成部分 Store(存储) 应用的唯一状态容器,存储整个应用的状态树,使用 createStore() 创建。 getState():获取当前状态。dispatch(action)&#xff…