Socket套接字(TCP流)篇

Socket套接字

  • ServerSocket
  • Socket
  • 案例演示
  • 小结

ServerSocket

ServerSocket是创建TCP服务端Socket的API.

ServerSocket构造方法:

方法签名方法说明
ServerSocket(int port)创建一个服务端套接字Socket,并绑定到指定端口

ServerSocket方法:

方法签名方法说明
Socket accept()开始监听指定端口(创建时绑定的端口),当有客户端连接时,返回一个服务端Socket对象,并基于该Socket建立与客户端的连接 ,否则阻塞等待
void close()关闭套接字

Socket

Socket是客户端Socket,或者是服务端中收到客户端建立连接的请求后,返回的服务端Socket.

Socket的构造方法:

方法签名方法说明
Socket(String host, int port)创建一个客户端套接字Socket, 并与对应主机,对应ip建立连接

Socket方法:

方法签名方法说明
InetAddress getInetAddress()返回套接字连接的地址
InputStream getInputStream()返回套接字的输入流
OutputStream getOutputStream()返回套接字的输出流

案例演示

TCP回显服务器

public class TcpEchoServer {private ServerSocket serverSocket = null;public TcpEchoServer(int port) throws IOException {serverSocket = new ServerSocket(port);}public void start() throws IOException {System.out.println("服务器启动!");while (true) {// 1. 处理客户端的连接// 把内核中的连接获取到应用程序中了,连接相当于一个个任务,放在队列中// 类似于生产者消费者模型// 如果没有客户端连接成功,就会进入阻塞.// 从队列中出序号最前面的连接, 与三次握手没有关系Socket clientSocket = serverSocket.accept();Thread thread = new Thread(() -> {try {processConnection(clientSocket);} catch (IOException e) {throw new RuntimeException(e);}});thread.start();}}private void processConnection(Socket clientSocket) throws IOException {System.out.printf("[%s:%d] 客户端上线!\n", clientSocket.getInetAddress().toString(), clientSocket.getPort());// 读取请求 计算响应  返回性相应// Socket 对象内部包含了两个字节流对象, 可以把这俩字节流对象获取到, 完成后续的读写工作try(InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream()) {// 一次连接中,可能会涉及多次请求和响应while (true) {// 1. 读取请求并解析, 为了读取方便,直接使用scannerScanner scanner = new Scanner(inputStream);if(!scanner.hasNext()) {System.out.printf("[%s:%d] 客户端下线\n", clientSocket.getInetAddress().toString(), clientSocket.getPort());break;}// 客户端发送的数据,得是文本数据// next()读取数据,一直读到空白符结束(换行,回车,空格,制表符,垂直制表符)String request = scanner.next();// 2. 根据请求计算响应String response = process(request);// 3. 把响应写回给客户端,把outputStream用PrintWriter包裹一下,方便发送数据PrintWriter writer = new PrintWriter(outputStream);// 使用 PrintWriter的println方法,把响应返回给客户端// 在结尾加上'\n', 客户端就可以用scanner.next()访问了writer.println(response);// 刷新缓冲区writer.flush();// 日志, 打印当前的请求信息System.out.printf("[%s:%d] req: %s, resp: %s\n",clientSocket.getInetAddress().toString(), clientSocket.getPort(),request, response);}} catch (IOException e) {throw new RuntimeException(e);} finally {// 不关闭会内存泄漏// 在finally中加入close方法,确保socket被关闭clientSocket.close();}}public String process(String request) {// 回显服务器return request;}public static void main(String[] args) throws IOException {TcpEchoServer server = new TcpEchoServer(900);server.start();}
}

TCP客户端

public class TcpEchoClient {private Socket socket = null;public TcpEchoClient(String serverIp, int serverPort) throws IOException {// new操作后,就完成了tcp连接的建立// 建立了三次握手socket = new Socket(serverIp, serverPort);}public void start() throws IOException {//System.out.println("客户端启动");Scanner scannerConsole = new Scanner(System.in);try(InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {while (true) {System.out.println("-> ");// 1. 从控制台输入字符串String request = scannerConsole.next();// 2. 把请求发送给服务器PrintWriter writer = new PrintWriter(outputStream);// 使用 println 带上换行. 后续服务器读取请求, 就可以使用 scanner.next 来获取了writer.println(request);// 确保数据发出去了writer.flush();// 3. 从服务器读取响应Scanner scannerNetWork = new Scanner(inputStream);String response = scannerNetWork.next();// 4. 把响应打印出来System.out.println(response);}}}public static void main(String[] args) throws IOException {TcpEchoClient client = new TcpEchoClient("127.0.0.1", 900);client.start();}
}

Scanner对象和PrintWriter没有进行close,是否有文件资源泄漏呢>
答案是不会的.
流对象持有的资源分为两部分:

  1. 内存(对象销毁,内存就回收了)
  2. 文件描述符
    while循环结束,内存被销毁.Scanner和PrintWriter没有文件描述符,有的是InputStream和OutputStream,准确说是Socket对象,把Socket对象关闭就可以了.
实际上客户端往往会发送大量的请求,我们可以使用线程池的方式来实现高并发.
但是即使使用了线程池,避免了频繁创建销毁线程.
毕竟是每个客户端对应一个线程,如果客户端很多,就需要创建大量线程,
对于服务器是开销很大的.
我们可以引入"IO多路复用"的方式解决多并发,利用"节流",是消耗的硬件资源更少了,减少
了线程的数量.

小结

本博客总结了Socket套接字(TCP流)的相关知识,有收获的小伙伴多多支持.

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

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

相关文章

在Ubuntu上安装JDK(Java Development Kit)

1、更新索引包在终端中执行以下命令,更新包索引: sudo apt update2、安装默认JDK版本:在Ubuntu 20.04及以上版本中,默认提供 OpenJDK作为JDK的选择。可以通过以下命令安装OpenJDK: sudo apt install default-jdk 这…

浅谈数据库、数据仓库、数据湖

这几年随着大数据的来临,数据仓库,数据湖炒的火热,但是他们跟传统的数据库有什么区别,今天我来简单的梳理一下他们的区别,如有不完整之处,请大家留言补充。 数据库、数据仓库和数据湖的定义 数据库&#…

Kubernetes - CentOS7搭建k8s_v1.18集群高可用(kubeadm/二进制包部署方式)实测配置验证手册

Kubernetes - CentOS7搭建k8s集群高可用(kubeadm/二进制包部署方式)实测配置验证手册 前言概述: 一、Kubernetes—k8s是什么 Kubernetes 这个名字源于希腊语,意为“舵手“或”飞行员"。 Kubernetes,简称K8s&#…

计算机网络大框架图形

如标题,精心画了一个计算机网络的框架性的图,包含了计算机网络的核心思想,在此分享和备份下。各层具体协议参考TCP/IP常用协议栈图解-CSDN博客

[论文阅读] 3D感知相关论文简单摘要

Adaptive Fusion of Single-View and Multi-View Depth for Autonomous Driving 提出了一个单、多视图融合深度估计系统,它自适应地集成了高置信度的单视图和多视图结果 动态选择两个分支之间的高置信度区域执行融合 提出了一个双分支网络,即一个以单…

uniapp 微信小程序 获取openid,手机号进行登录,配合后端

流程&#xff1a;登录注册功能,通过uni.getUserProfile获取wxcode,通过wxcode传给后端获取openid,sessionkey,unionid。 通过<u-button type"success" open-type"getPhoneNumber" getphonenumber"decryptPhoneNumber">一键登录</u-butt…

HTML批量文件上传方案——图像预览方式

作者:私语茶馆 1.HTML多文件上传的关键方案 多文件上传包括:文件有效性校验,文件预览、存储和进度展示多个方面,本章节介绍的是文件预览的实现方案。 2.文件上传前预览 2.1.效果 选择文件前: 选择文件后: 2.2.CSS文件代码 StorageCenter.css代码 html {font-family:…

uniapp app权限说明弹框2024.4.23更新

华为上架被拒绝 用uni-app开发的app&#xff0c;上架华为被拒&#xff0c;问题如下&#xff1a; 您的应用在运行时&#xff0c;未见向用户告知权限申请的目的&#xff0c;向用户索取&#xff08;电话、相机、存储&#xff09;等权限&#xff0c;不符合华为应用市场审核标准。…

HWOD:输出单向链表中倒数第k个节点

一、知识点 不确定输入的数据有多少组时&#xff0c;可以用 if(scanf()>0) 作为判断条件 如果要处理多组数据&#xff0c;不一定要为每组数据申请空间。可以存储一组&#xff0c;处理一组&#xff0c;存储数据的空间清零之后继续存储下一组数据。额外申请空间&#xff0…

MySQL函数之单行函数

1.前言 我们在使用 SQL 语言的时候&#xff0c;不是直接和这门语言打交道&#xff0c;而是通过它使用不同的数据库软件&#xff0c;即DBMS。DBMS 之间的差异性很大&#xff0c;远大于同一个语言不同版本之间的差异。实际上&#xff0c;只有很少的函数是被 DBMS 同时支持的。比…

AI助手对决:ChatGPT vs 文心一言

背景介绍 在当今人工智能技术飞速发展的时代&#xff0c;AI助手已经成为我们日常生活中不可或缺的一部分。而在众多AI助手中&#xff0c;ChatGPT和文心一言可以说是备受瞩目的两大代表&#xff0c;它们在智能回复、语言准确性、知识库丰富度等方面都有着自己的特点和优…

微信小程序:12.页面导航

什么是页面导航 页面导航指的是页面之间的相互跳转。例如&#xff0c;浏览器中实现的页面导航的方式有两种&#xff1a; 连接location.href 小程序中实现页面导航的两种方式 声明式导航 在页面上声明一个导航组件 通过点击组件实现页面跳转 导航TabBar页面 是指配置TabB…

Unity自动化之自动构建图集与压缩

文章目录 前言一、UI图集的压缩unity2020之前的版本使用图集unity2020之后的版本使用图集 二、非UI图集压缩总结 前言 为降低DrawCall&#xff0c;我们需要将多个图片构建在图集上。同时还有个好处&#xff0c;可以自动补齐图片补齐2的幂次方或正方形图&#xff0c;这样便可以…

【CV】特征匹配FAST和MSER

特征匹配是计算机视觉领域的重要概念&#xff0c;涉及在图像中寻找关键点和描述符。FAST和MSER是两种常用的关键点检测算法。 FAST (Features from Accelerated Segment Test) FAST算法是一种快速角点检测器。它基于像素强度比较&#xff0c;在一个圆圈内进行强度对比&#x…

解决uniapp修改内置组件样式,在微信中不生效问题

下面是作者在开发工作中遇到的问题&#xff0c;踩坑几小时最后解决的办法。 接下来以UNIAPP文档中的内置组件 slider 为例 接下来直接上样式代码&#xff1a; <style lang"scss" scoped>::v-deep .wx-slider-wrapper {height: 100% !important;}::v-deep .w…

前端实现将当前页面内容下载成图片(图片可做到高清画质)

插件背景&#xff1a; html2canvas可以把你想要转变的元素变为图片&#xff0c;使用file-saver下载图片。 1、安装html2canvas、file-saver npm install html2canvasnpm install file-saver --save 2、在Vue组件中引入并使用html2canvas、file-saver import html2canvas fro…

Django 学习 笔记

Django 一、模型models 继承django.db.models.Model 1.模型字段 / 模型字段选项参考&#xff1a; 官网&#xff1a;https://docs.djangoproject.com/zh-hans/3.2/ref/models/fields/#common-model-field-options 2.模型Meta选项(定义模型类的属性)&#xff1a; csdn: https:/…

C#基础|对象初始化器与构造方法对比总结

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 01 对象初始化器的作用 为了更加灵活的初始化对象的“属性”&#xff0c;是对构造化方法的补充。 02 构造方法总结 2.1、存在的必要性&#xff1a;一个类中&#xff0c;至少要有一个构造方法&#xff08;有无参数均…

五一节前的信息系统的安全保障工作

文章目录 保障流程制定安全保障计划确定检查人员确定检查内容实施检查风险评估修复漏洞定期复查 保障内容系统安全检查网络安全检查数据安全检查应用安全检查用户安全检查安全政策和流程检查 关闭信息系统说明制定关闭计划备份数据通知相关人员停止系统服务关闭系统设备监控关闭…

合合信息引领AI场景化革新,供应链金融智能化审核全面升级!

官.网地址&#xff1a;合合TextIn - 合合信息旗下OCR云服务产品 随着供给侧结构性改革的深入推进和产业结构的不断升级&#xff0c;金融机构在监管部门的指导下&#xff0c;积极拓展供应链金融业务&#xff0c;取得了显著成效。这一举措有效缓解了上下游中小企业的融资困难&a…