Socket网络编程(三)——TCP快速入门

概述

  1. TCP是什么
    英语:Transmission Control Protocol,缩写为 TCP
    TCP是传输控制协议;是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义
    与UDP一样完成第四层传输层所指定的功能与职责

  2. TCP的机制
    三次握手、四次挥手
    具有校验机制、可靠、数据传输稳定

  3. TCP能做什么
    聊天消息传输、推送
    单人语音、视频聊天等
    几乎UDP能做的都能做,但需要考虑复杂性、性能问题
    限制:无法进行广播,多播等操作

TCP连接可靠性

1. 三次握手过程

20240228-020352-Ph.png
三次握手的过程包括:

第一次握手:客户端发送SYN包,携带自己的序列号。
第二次握手:服务器端回复SYN+ACK包,确认收到客户端的SYN包,并携带自己的序列号。
第三次握手:客户端回复ACK包,确认收到的SYN+ACK包,完成握手过程。

这个过程确保了后续数据的可靠传输和完整性,保障了网络通信的稳定性和可靠性。

2. 四次挥手过程

20240228-020858-ym.png
四次挥手是TCP协议中用于终止连接的过程,这个过程涉及到客户端和服务端之间发送四个数据包。由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。在四次挥手中,首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。1234

以下是四次挥手的详细步骤:

第一次挥手:客户端发送一个FIN报文,用来关闭客户端到服务器的数据传送。此时客户端进入FIN_WAIT_1状态.
第二次挥手:服务器收到FIN报文后,发送一个ACK报文作为响应,确认序号为收到序号加1。此时服务器进入CLOSE_WAIT状态。
第三次挥手:服务器完成数据发送任务后,发送一个FIN报文,用来关闭服务器到客户端的数据传送。此时服务器进入LAST_ACK状态。
第四次挥手:客户端收到FIN报文后,发送一个ACK报文作为响应,确认序号为收到序号加1。此时客户端进入TIME_WAIT状态。客户端在等待一段时间(通常为2MSL,即最大报文段寿命)后,如果没有收到服务器的任何响应,则进入CLOSE状态。

这个过程确保了双方都能正确关闭连接,避免了数据丢失。

3. 为什么挥手需要四次?

由于 TCP 的半关闭(half-close)特性,TCP 提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。

任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。
通俗的来说,两次握手就可以释放一端到另一端的 TCP 连接,完全释放连接一共需要四次握手。

可以用下面这个例子理解:

举个例子:A 和 B 打电话,通话即将结束后,A 说 “我没啥要说的了”,B 回答 “我知道了”,于是 A 向 B 的连接释放了。但是 B 可能还会有要说的话,于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”,A 回答“知道了”,于是 B 向 A 的连接释放了,这样整个通话就结束了。

传输可靠性

  1. 排序、顺序发送、顺序组装
  2. 丢弃、超时
  3. 重发机制-定时器

数据传输示意图
20240228-022539-2k.png

TCP核心API

socket():创建—个Socket
bind():绑定一个Socket到一个本地地址和端口上
connect():连接到远程套接字
accept():接受一个新的连接
write():把数据写入到Socket输出流
read():从Socket输入流读取数据

客户端Socket创建流程:
20240228-013916-lO.png

服务端ServerSocket创建流程:
20240228-014016-IO.png

Socket和进程的关系:
20240228-014241-Xq.png

TCP传输初始化配置&建立连接

  1. 初始化服务器TCP链接监听
  2. 初始化客户端发起链接操作
  3. 服务器Socket链接处理

客户端创建Socket建立连接

  1. 创建Socket基本方法和构造函数
private static Socket createSocket() throws IOException {/*// 无代理模式,等效于空构造函数Socket socket = new Socket(Proxy.NO_PROXY);// 新建一份具有HTTP代理的套接字,传输数据将通过www.baidu.com:8080端口转发Proxy proxy = new Proxy(Proxy.Type.HTTP,new InetSocketAddress(Inet4Address.getByName("www.baidu.com"), 8800));socket = new Socket(proxy);// 新建一个套接字,并且直接链接到本地20000的服务器上socket = new Socket("localhost", PORT);// 新建一个套接字,并且直接链接到本地20000的服务器上socket = new Socket(Inet4Address.getLocalHost(), PORT);// 新建一个套接字,并且直接链接到本地20000的服务器上,并且绑定到本地20001端口上socket = new Socket("localhost", PORT, Inet4Address.getLocalHost(), LOCAL_PORT);socket = new Socket(Inet4Address.getLocalHost(), PORT, Inet4Address.getLocalHost(), LOCAL_PORT);*/Socket socket = new Socket();// 绑定到本地20001端口socket.bind(new InetSocketAddress(Inet4Address.getLocalHost(), LOCAL_PORT));return socket;}
  1. 初始化Socket的基本配置
private static void initSocket(Socket socket) throws SocketException {// 设置读取超时时间为2秒socket.setSoTimeout(2000);// 是否复用未完全关闭的Socket地址,对于指定bind操作后的套接字有效socket.setReuseAddress(true);// 是否开启Nagle算法socket.setTcpNoDelay(true);// 是否需要在长时无数据响应时发送确认数据(类似心跳包),时间大约为2小时socket.setKeepAlive(true);// 对于close关闭操作行为进行怎样的处理;默认为false,0// false、0:默认情况,关闭时立即返回,底层系统接管输出流,将缓冲区内的数据发送完成// true、0:关闭时立即返回,缓冲区数据抛弃,直接发送RST结束命令到对方,并无需经过2MSL等待// true、200:关闭时最长阻塞200毫秒,随后按第二情况处理socket.setSoLinger(true, 20);// 是否让紧急数据内敛,默认false;紧急数据通过 socket.sendUrgentData(1);发送socket.setOOBInline(true);// 设置接收发送缓冲器大小socket.setReceiveBufferSize(64 * 1024 * 1024);socket.setSendBufferSize(64 * 1024 * 1024);// 设置性能参数:短链接,延迟,带宽的相对重要性socket.setPerformancePreferences(1, 1, 0);}
  1. 客户端手动连接
public static void main(String[] args) throws IOException {Socket socket = createSocket();initSocket(socket);// 链接到本地20000端口,超时时间3秒,超过则抛出超时异常socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), PORT), 3000);System.out.println("已发起服务器连接,并进入后续流程~");System.out.println("客户端信息:" + socket.getLocalAddress() + " P:" + socket.getLocalPort());System.out.println("服务器信息:" + socket.getInetAddress() + " P:" + socket.getPort());try {// 发送接收数据todo(socket);} catch (Exception e) {System.out.println("异常关闭");}// 释放资源socket.close();System.out.println("客户端已退出~");}

服务端创建ServerSocket监听连接

  1. 创建ServerSocket方法
private static ServerSocket createServerSocket() throws IOException {// 创建基础的ServerSocketServerSocket serverSocket = new ServerSocket();// 绑定到本地端口20000上,并且设置当前可允许等待链接的队列为50个//serverSocket = new ServerSocket(PORT);// 等效于上面的方案,队列设置为50个//serverSocket = new ServerSocket(PORT, 50);// 与上面等同// serverSocket = new ServerSocket(PORT, 50, Inet4Address.getLocalHost());return serverSocket;}
  1. 初始化ServerSocket配置
private static void initServerSocket(ServerSocket serverSocket) throws IOException {// 是否复用未完全关闭的地址端口serverSocket.setReuseAddress(true);// 等效Socket#setReceiveBufferSizeserverSocket.setReceiveBufferSize(64 * 1024 * 1024);// 设置serverSocket#accept超时时间// serverSocket.setSoTimeout(2000);// 设置性能参数:短链接,延迟,带宽的相对重要性serverSocket.setPerformancePreferences(1, 1, 1);}
  1. 监听服务端固定端口,并且接受客户端建立连接
private static final int PORT = 20000;public static void main(String[] args) throws IOException {ServerSocket server = createServerSocket();initServerSocket(server);// 绑定到本地端口上server.bind(new InetSocketAddress(Inet4Address.getLocalHost(), PORT), 50);System.out.println("服务器准备就绪~");System.out.println("服务器信息:" + server.getInetAddress() + " P:" + server.getLocalPort());// 等待客户端连接for (; ; ) {// 得到客户端Socket client = server.accept();// 客户端构建异步线程ClientHandler clientHandler = new ClientHandler(client);// 启动线程clientHandler.start();}}

ServerSocket 和 Socket的关系

serverSocket 和 Socket 都是 Java 中用于网络通信的类,但它们有不同的作用。

Socket 是用于建立连接的类,它可以让客户端和服务器之间相互通信。

ServerSocket 是用于监听连接请求的类,它在服务器端等待客户端的连接请求,并在连接成功后与客户端建立对应的 Socket 连接。

具体工作原理可以简单描述为:

当客户端与服务器建立连接时,客户端通过创建 Socket 对象实现,服务器端则通过创建 ServerSocket 对象实现。
客户端向服务器发送连接请求,请求中包含了要连接的服务器地址和端口号。
ServerSocket 接收到连接请求后,会生成一个 Socket 对象与客户端连接,并返回此连接对应的 Socket 对象。
客户端和服务器之间即可通过这个连接进行通信。

总之,ServerSocket 是用于监听连接请求的类,而 Socket 则是用于实现连接并进行通信的类。

Socket基本数据类型传输

基础类型数据传输

  • byte、 char、 short
  • boolean、 int、 long
  • float、 double、 string

客户端数据传输

  1. 客户端使用Socket输出流将客户端的数据传输出去
  2. 建立连接之后将各种数据类型的数据转换成byte字节数组,然后通过ByteBuffer工具统一放入字节流
    (这里使用到了一个ByteBuffer工具,这是一个字节缓冲区,后面会详细介绍)
  3. 最后通过Socket的输出流把数据发送给服务端

代码如下:

private static void todo(Socket client) throws IOException {// 得到Socket输出流OutputStream outputStream = client.getOutputStream();// 得到Socket输入流InputStream inputStream = client.getInputStream();byte[] buffer = new byte[256];ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);// bytebyteBuffer.put((byte) 126);// charchar c = 'a';byteBuffer.putChar(c);// intint i = 2323123;byteBuffer.putInt(i);// boolboolean b = true;byteBuffer.put(b ? (byte) 1 : (byte) 0);// Longlong l = 298789739;byteBuffer.putLong(l);// floatfloat f = 12.345f;byteBuffer.putFloat(f);// doubledouble d = 13.31241248782973;byteBuffer.putDouble(d);// StringString str = "Hello你好!";byteBuffer.put(str.getBytes());// 发送到服务器outputStream.write(buffer, 0, byteBuffer.position() + 1);// 接收服务器返回int read = inputStream.read(buffer);System.out.println("收到数量:" + read);// 资源释放outputStream.close();inputStream.close();}

服务端数据接收

  1. 获取监听到连接的客户端Socket套接字流
  2. 将流读取出来,转换成ByteBuffer
  3. 最后根据不同的数据类型将ByteBuffer中的数据读取并且打印出来
/*** 客户端消息处理*/private static class ClientHandler extends Thread {private Socket socket;ClientHandler(Socket socket) {this.socket = socket;}@Overridepublic void run() {super.run();System.out.println("新客户端连接:" + socket.getInetAddress() +" P:" + socket.getPort());try {// 得到套接字流OutputStream outputStream = socket.getOutputStream();InputStream inputStream = socket.getInputStream();byte[] buffer = new byte[256];int readCount = inputStream.read(buffer);ByteBuffer byteBuffer = ByteBuffer.wrap(buffer, 0, readCount);// bytebyte be = byteBuffer.get();// charchar c = byteBuffer.getChar();// intint i = byteBuffer.getInt();// boolboolean b = byteBuffer.get() == 1;// Longlong l = byteBuffer.getLong();// floatfloat f = byteBuffer.getFloat();// doubledouble d = byteBuffer.getDouble();// Stringint pos = byteBuffer.position();String str = new String(buffer, pos, readCount - pos - 1);System.out.println("收到数量:" + readCount + " 数据:"+ be + "\n"+ c + "\n"+ i + "\n"+ b + "\n"+ l + "\n"+ f + "\n"+ d + "\n"+ str + "\n");outputStream.write(buffer, 0, readCount);outputStream.close();inputStream.close();} catch (Exception e) {System.out.println("连接异常断开");} finally {// 连接关闭try {socket.close();} catch (IOException e) {e.printStackTrace();}}System.out.println("客户端已退出:" + socket.getInetAddress() +" P:" + socket.getPort());}}

TCP连接客户端、服务端完整代码

服务端代码:

package cn.kt.SocketDemoL4;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;public class Server {private static final int PORT = 20000;public static void main(String[] args) throws IOException {ServerSocket server = createServerSocket();initServerSocket(server);// 绑定到本地端口上server.bind(new InetSocketAddress(Inet4Address.getLocalHost(), PORT), 50);System.out.println("服务器准备就绪~");System.out.println("服务器信息:" + server.getInetAddress() + " P:" + server.getLocalPort());// 等待客户端连接for (; ; ) {// 得到客户端Socket client = server.accept();// 客户端构建异步线程ClientHandler clientHandler = new ClientHandler(client);// 启动线程clientHandler.start();}}private static ServerSocket createServerSocket() throws IOException {// 创建基础的ServerSocketServerSocket serverSocket = new ServerSocket();// 绑定到本地端口20000上,并且设置当前可允许等待链接的队列为50个//serverSocket = new ServerSocket(PORT);// 等效于上面的方案,队列设置为50个//serverSocket = new ServerSocket(PORT, 50);// 与上面等同// serverSocket = new ServerSocket(PORT, 50, Inet4Address.getLocalHost());return serverSocket;}private static void initServerSocket(ServerSocket serverSocket) throws IOException {// 是否复用未完全关闭的地址端口serverSocket.setReuseAddress(true);// 等效Socket#setReceiveBufferSizeserverSocket.setReceiveBufferSize(64 * 1024 * 1024);// 设置serverSocket#accept超时时间// serverSocket.setSoTimeout(2000);// 设置性能参数:短链接,延迟,带宽的相对重要性serverSocket.setPerformancePreferences(1, 1, 1);}/*** 客户端消息处理*/private static class ClientHandler extends Thread {private Socket socket;ClientHandler(Socket socket) {this.socket = socket;}@Overridepublic void run() {super.run();System.out.println("新客户端连接:" + socket.getInetAddress() +" P:" + socket.getPort());try {// 得到套接字流OutputStream outputStream = socket.getOutputStream();InputStream inputStream = socket.getInputStream();byte[] buffer = new byte[256];int readCount = inputStream.read(buffer);ByteBuffer byteBuffer = ByteBuffer.wrap(buffer, 0, readCount);// bytebyte be = byteBuffer.get();// charchar c = byteBuffer.getChar();// intint i = byteBuffer.getInt();// boolboolean b = byteBuffer.get() == 1;// Longlong l = byteBuffer.getLong();// floatfloat f = byteBuffer.getFloat();// doubledouble d = byteBuffer.getDouble();// Stringint pos = byteBuffer.position();String str = new String(buffer, pos, readCount - pos - 1);System.out.println("收到数量:" + readCount + " 数据:"+ be + "\n"+ c + "\n"+ i + "\n"+ b + "\n"+ l + "\n"+ f + "\n"+ d + "\n"+ str + "\n");outputStream.write(buffer, 0, readCount);outputStream.close();inputStream.close();} catch (Exception e) {System.out.println("连接异常断开");} finally {// 连接关闭try {socket.close();} catch (IOException e) {e.printStackTrace();}}System.out.println("客户端已退出:" + socket.getInetAddress() +" P:" + socket.getPort());}}
}

客户端代码

package cn.kt.SocketDemoL4;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;public class Client {private static final int PORT = 20000;private static final int LOCAL_PORT = 20001;public static void main(String[] args) throws IOException {Socket socket = createSocket();initSocket(socket);// 链接到本地20000端口,超时时间3秒,超过则抛出超时异常socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), PORT), 3000);System.out.println("已发起服务器连接,并进入后续流程~");System.out.println("客户端信息:" + socket.getLocalAddress() + " P:" + socket.getLocalPort());System.out.println("服务器信息:" + socket.getInetAddress() + " P:" + socket.getPort());try {// 发送接收数据todo(socket);} catch (Exception e) {System.out.println("异常关闭");}// 释放资源socket.close();System.out.println("客户端已退出~");}private static Socket createSocket() throws IOException {/*// 无代理模式,等效于空构造函数Socket socket = new Socket(Proxy.NO_PROXY);// 新建一份具有HTTP代理的套接字,传输数据将通过www.baidu.com:8080端口转发Proxy proxy = new Proxy(Proxy.Type.HTTP,new InetSocketAddress(Inet4Address.getByName("www.baidu.com"), 8800));socket = new Socket(proxy);// 新建一个套接字,并且直接链接到本地20000的服务器上socket = new Socket("localhost", PORT);// 新建一个套接字,并且直接链接到本地20000的服务器上socket = new Socket(Inet4Address.getLocalHost(), PORT);// 新建一个套接字,并且直接链接到本地20000的服务器上,并且绑定到本地20001端口上socket = new Socket("localhost", PORT, Inet4Address.getLocalHost(), LOCAL_PORT);socket = new Socket(Inet4Address.getLocalHost(), PORT, Inet4Address.getLocalHost(), LOCAL_PORT);*/Socket socket = new Socket();// 绑定到本地20001端口socket.bind(new InetSocketAddress(Inet4Address.getLocalHost(), LOCAL_PORT));return socket;}private static void initSocket(Socket socket) throws SocketException {// 设置读取超时时间为2秒socket.setSoTimeout(2000);// 是否复用未完全关闭的Socket地址,对于指定bind操作后的套接字有效socket.setReuseAddress(true);// 是否开启Nagle算法socket.setTcpNoDelay(true);// 是否需要在长时无数据响应时发送确认数据(类似心跳包),时间大约为2小时socket.setKeepAlive(true);// 对于close关闭操作行为进行怎样的处理;默认为false,0// false、0:默认情况,关闭时立即返回,底层系统接管输出流,将缓冲区内的数据发送完成// true、0:关闭时立即返回,缓冲区数据抛弃,直接发送RST结束命令到对方,并无需经过2MSL等待// true、200:关闭时最长阻塞200毫秒,随后按第二情况处理socket.setSoLinger(true, 20);// 是否让紧急数据内敛,默认false;紧急数据通过 socket.sendUrgentData(1);发送socket.setOOBInline(true);// 设置接收发送缓冲器大小socket.setReceiveBufferSize(64 * 1024 * 1024);socket.setSendBufferSize(64 * 1024 * 1024);// 设置性能参数:短链接,延迟,带宽的相对重要性socket.setPerformancePreferences(1, 1, 0);}private static void todo(Socket client) throws IOException {// 得到Socket输出流OutputStream outputStream = client.getOutputStream();// 得到Socket输入流InputStream inputStream = client.getInputStream();byte[] buffer = new byte[256];ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);// bytebyteBuffer.put((byte) 126);// charchar c = 'a';byteBuffer.putChar(c);// intint i = 2323123;byteBuffer.putInt(i);// boolboolean b = true;byteBuffer.put(b ? (byte) 1 : (byte) 0);// Longlong l = 298789739;byteBuffer.putLong(l);// floatfloat f = 12.345f;byteBuffer.putFloat(f);// doubledouble d = 13.31241248782973;byteBuffer.putDouble(d);// StringString str = "Hello你好!";byteBuffer.put(str.getBytes());// 发送到服务器outputStream.write(buffer, 0, byteBuffer.position() + 1);// 接收服务器返回int read = inputStream.read(buffer);System.out.println("收到数量:" + read);// 资源释放outputStream.close();inputStream.close();}
}

执行结果

  1. 运行服务端
    20240228-151715-ZN.png

  2. 运行客户端
    20240228-151741-r9.png

  3. 服务端接收到消息并输出

20240228-151758-6Y.png

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

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

相关文章

postman测试接口

1、postman测试接口 (1)首先安装postman 下载地址:Download Postman | Get Started for Free 选择对应版本下载,然后安装即可 (2)使用postman发送请求 比如以下这个请求例子: 使用postman发…

UE4 材质多张图片拼接成一张图片(此处用2×2拼接)

UE4 材质多张图片拼接成一张图片&#xff08;此处用22拼接&#xff09; //TexCoord,TextureA,TextureB,TextureC,TextureDfloat3 ReturnTexture TextureA; if(TexCoord.x < 0.5 && TexCoord.y < 0.5) {ReturnTexture TextureA; } else if(TexCoord.x > 0.5…

php docx,pptx,excel表格上传阿里云,腾讯云存储后截取第一页生成缩略图

php把word转图片的方法:首先给服务器安装libreoffice;然后使用exec函数来调用命令行操作;最后通过“exec(“soffice --headless --invisible…””方法把word转图片即可。 服务器环境:centos7 *集成环境:宝塔 我们开始给服务器安装libreoffice 直接执行下面的代码就可以…

代码随想录Leetcode213. 打家劫舍 II

题目&#xff1a; 代码(首刷看解析 2024年2月29日&#xff09;&#xff1a; class Solution { public:int robRange(vector<int>& nums, int start, int end) {if (start end) return nums[start];vector<int> dp(nums.size(), 0); // 遍历dp[start] nums[s…

【Oracle】玩转Oracle数据库(七):RMAN恢复管理器

前言 嘿&#xff0c;数据库大魔法师们&#xff01;准备好迎接新的技术大招了吗&#xff1f;今天我们要探索的是Oracle数据库中的神奇利器——RMAN恢复管理器&#xff01;&#x1f6e1;️&#x1f4be; 在这篇博文【Oracle】玩转Oracle数据库&#xff08;七&#xff09;&#xf…

mov和mp4格式哪个好?专业讲师告诉你答案【详】

在数字化时代&#xff0c;我们经常面临着选择视频格式的困境&#xff0c;尤其是需要在不同设备和平台上播放或分享视频时。在这些选择中&#xff0c;MOV和MP4格式是两种最常见的选项之一。 然而&#xff0c;mov和mp4格式哪个好呢&#xff1f;这个问题并不容易回答&#xff0c;…

C++重点---STL简介

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、STL简介 STL&#xff08;Standard Template Library&#xff09;是C标准库中的一个重要组成部分&#xff0c;它提供了…

LabVIEW水下温盐深数据一体化采集与分析

LabVIEW水下温盐深数据一体化采集与分析 开发一个基于LabVIEW的水下温盐深数据一体化采集与分析系统&#xff0c;实现海洋环境监测的自动化和精确化。通过集成温度、盐度和深度传感器&#xff0c;结合USB数据采集卡&#xff0c;利用LabVIEW软件开发的图形化界面&#xff0c;实…

理解计算着色器中glsl语言的内置变量

概要 本文通过示例的方式&#xff0c;着重解释以下几个内置变量&#xff1a; gl_WorkGroupSizegl_NumWorkGroupsgl_LocalInvocationIDgl_WorkGroupIDgl_GlobalInvocationID 基本概念 局部工作组与工作项 一个3x2x1的局部工作组示例如下&#xff0c;每个小篮格子表示一个工作项…

403页面绕过

403页面绕过 文章目录 403页面绕过姿势一: 端口利用姿势二&#xff1a;修改HOST姿势三&#xff1a;覆盖请求URL姿势四&#xff1a;Referer标头绕过姿势五&#xff1a;代理IP姿势六&#xff1a;扩展名绕过 姿势一: 端口利用 拿到客户给的地址后&#xff0c;首先进行信息收集。端…

[数据集][目标检测]游泳者溺水数据集VOC+YOLO格式2类别895张

数据集制作单位&#xff1a;未来自主研究中心(FIRC) 数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;895 标注数量(xml文件个数)&#xff1a…

js 面试 什么是WebSockets?HTTP和HTTPS有什么不同?web worker是什么?

概念&#xff1a; webSocket 是一种在客户端和服务端之间建立持久连接的协议&#xff0c;它提供全双工通信通道&#xff0c;是服务器可以主动向客户端推送数据&#xff0c;同时也可以接受客户端发送的数据。 1 webSocket与https区别&#xff1f; 在网络通信中&#xff0c;We…

Android进阶之路 - RecyclerView停止滑动后Item自动居中(SnapHelper辅助类)

之前一直没注意 SnapHelper 辅助类的功能&#xff0c;去年的时候看到项目中仅通过俩行代码设置 RecyclerView 后就提升了用户体验&#xff0c;觉得还是很有必要了解一下&#xff0c;尝试过后才发现其 PagerSnapHelper、LinearSnapHelper 子类可以作用于不同场景&#xff0c;且听…

vue a-table 实现指定字段相同数据合并行

vue a-table 实现相同数据合并行 实现效果代码实现cloums数据格式数据源格式合并代码 实现效果 代码实现 cloums数据格式 const getColumns function () {return [{title: "分类",dataIndex: "checked",width: "150px",customRender: (text, …

在SAP HANA中使用OData(二)

通常有两种方式通过OData来暴露SAP HANA中的数据库对象&#xff0c;一是直接使用Database Object&#xff0c;比如前一篇和本篇文章介绍的例子&#xff0c;这种方式针对于数据已经存在于SAP HANA中&#xff0c;在Repository中没有对应的设计时对象(Design-time Object)&#xf…

Qt SQLite的创建和使用

重点&#xff1a; 1.SQLite创建数据库内容方法 链接&#xff1a;SQLite Expert Personal的简单使用-CSDN博客 2.和数据库进行链接方法 QSqlDatabase DB; //数据库连接bool MainWindow::openDatabase(QString aFile) {DBQSqlDatabase::addDatabase("QSQLITE"); /…

vue - - - - - vue3使用draggable拖拽组件

vue3使用draggable拖拽组件 一、组件安装二、插件使用三、遇到的问题1. missing required prop&#xff1a; “itemKey” 一、组件安装 yarn add vuedraggablenext // or npm i -S vuedraggablenext二、插件使用 <template><draggableitem-key"id"class&q…

【系统分析师】-软件工程

1、信息系统的生命周期 1、四阶段划分 立项阶段&#xff1a;企业全局、形成概念、需求分析。包含【系统分析师】-系统规划-CSDN博客开发阶段&#xff1a;总体规划--系统分析--设计--实施--验收运维阶段&#xff1a;通过验收、移交之后消亡阶段&#xff1a;更新改造、功能扩展…

【EFK】基于K8S构建EFK+logstash+kafka日志平台

基于K8S构建EFKlogstashkafka日志平台 一、常见日志收集方案1.1、EFK1.2、ELK Stack1.3、ELK filbeat1.4、其他方案 二、EFK组件介绍2.1、Elasticsearch组件2.2、Filebeat组件【1】 Filebeat和beat关系【2】Filebeat是什么【3】Filebeat工作原理【4】传输方案 2.3、Logstash组件…

Apache Bench(ab )压力测试

目录 参数说明示例1&#xff1a;压力测试示例2&#xff1a;测试post接口post数据文件该如何编写&#xff1f; apr_pollset_poll: The timeout specified has expired (70007)apr_socket_recv: Connection reset by peer (104)参考 参数说明 官方文档参考这里。 ab -c 100 -n …