分析s3超时
2026-08-25dsv鉴定器反馈访问s3超时

/*
* fasttcping.c
*
* TCP ping + payload + HTTP CONNECT proxy
*
* Build:
* gcc -O2 -Wall -Wextra -o fasttcping fasttcping.c
*
* Examples:
*
* 1. TCP connect ping
* ./fasttcping 10.252.16.60 5432
*
* 2. Send 64-byte payload after connect
* ./fasttcping -s 64 10.252.16.60 5432
*
* 3. 1000 probes, no interval
* ./fasttcping -c 1000 -i 0 10.252.16.60 5432
*
* 4. HTTP CONNECT proxy
* ./fasttcping \
* -P 10.252.1.10:3128 \
* 10.252.16.60 5432
*
* 5. Proxy authentication
* ./fasttcping \
* -P 10.252.1.10:3128 \
* -U user \
* -W password \
* 10.252.16.60 5432
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <time.h>
#define DEFAULT_PORT 80
#define DEFAULT_COUNT 4
#define DEFAULT_TIMEOUT 1000
#define DEFAULT_INTERVAL 1000
#define MAX_PROXY_RESPONSE 8192
#define MAX_PAYLOAD 65535
#define MAX_SAMPLES 1000000
typedef struct {
const char *host;
int port;
int count;
int timeout_ms;
int interval_ms;
int payload_size;
char proxy_host[256];
int proxy_port;
int use_proxy;
char proxy_user[256];
char proxy_pass[256];
int proxy_auth;
} config_t;
typedef struct {
double *values;
int count;
int capacity;
} samples_t;
/* ============================================================
* Time
* ============================================================ */
static uint64_t now_us(void)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (uint64_t)ts.tv_sec * 1000000ULL +
(uint64_t)ts.tv_nsec / 1000ULL;
}
/* ============================================================
* Sleep
* ============================================================ */
static void sleep_ms(int ms)
{
if (ms <= 0)
return;
struct timespec ts;
ts.tv_sec = ms / 1000;
ts.tv_nsec = (long)(ms % 1000) * 1000000L;
nanosleep(&ts, NULL);
}
/* ============================================================
* Non-blocking
* ============================================================ */
static int set_nonblock(int fd)
{
int flags;
flags = fcntl(fd, F_GETFL, 0);
if (flags < 0)
return -1;
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
/* ============================================================
* Wait socket
* ============================================================ */
static int wait_fd(int fd, short events, int timeout_ms)
{
struct pollfd pfd;
pfd.fd = fd;
pfd.events = events;
pfd.revents = 0;
while (1) {
int ret = poll(&pfd, 1, timeout_ms);
if (ret > 0) {
if (pfd.revents & (POLLERR | POLLHUP | POLLNVAL))
return -1;
if (pfd.revents & events)
return 0;
return -1;
}
if (ret == 0) {
errno = ETIMEDOUT;
return -1;
}
if (errno == EINTR)
continue;
return -1;
}
}
/* ============================================================
* Connect TCP
* ============================================================ */
static int tcp_connect(
const char *host,
int port,
int timeout_ms
)
{
struct addrinfo hints;
struct addrinfo *res = NULL;
struct addrinfo *rp;
char portstr[16];
int fd = -1;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
snprintf(
portstr,
sizeof(portstr),
"%d",
port
);
if (getaddrinfo(
host,
portstr,
&hints,
&res
) != 0) {
return -1;
}
for (rp = res; rp != NULL; rp = rp->ai_next) {
fd = socket(
rp->ai_family,
rp->ai_socktype,
rp->ai_protocol
);
if (fd < 0)
continue;
if (set_nonblock(fd) < 0) {
close(fd);
fd = -1;
continue;
}
int ret = connect(
fd,
rp->ai_addr,
rp->ai_addrlen
);
if (ret == 0)
break;
if (errno != EINPROGRESS) {
close(fd);
fd = -1;
continue;
}
if (wait_fd(
fd,
POLLOUT,
timeout_ms
) < 0) {
close(fd);
fd = -1;
continue;
}
int error = 0;
socklen_t len = sizeof(error);
if (getsockopt(
fd,
SOL_SOCKET,
SO_ERROR,
&error,
&len
) < 0) {
close(fd);
fd = -1;
continue;
}
if (error != 0) {
errno = error;
close(fd);
fd = -1;
continue;
}
break;
}
freeaddrinfo(res);
return fd;
}
/* ============================================================
* Send all
* ============================================================ */
static int send_all(
int fd,
const void *buf,
size_t len,
int timeout_ms
)
{
const char *p = (const char *)buf;
size_t sent = 0;
uint64_t start = now_us();
while (sent < len) {
int elapsed =
(int)((now_us() - start) / 1000ULL);
if (elapsed >= timeout_ms) {
errno = ETIMEDOUT;
return -1;
}
int remain = timeout_ms - elapsed;
if (wait_fd(
fd,
POLLOUT,
remain
) < 0) {
return -1;
}
ssize_t n = send(
fd,
p + sent,
len - sent,
MSG_NOSIGNAL
);
if (n > 0) {
sent += (size_t)n;
continue;
}
if (n < 0 &&
(errno == EAGAIN ||
errno == EWOULDBLOCK ||
errno == EINTR)) {
continue;
}
return -1;
}
return 0;
}
/* ============================================================
* Read HTTP Proxy response
* ============================================================ */
static int proxy_read_response(
int fd,
int timeout_ms
)
{
char buf[MAX_PROXY_RESPONSE];
size_t used = 0;
uint64_t start = now_us();
while (used < sizeof(buf) - 1) {
int elapsed =
(int)((now_us() - start) / 1000ULL);
if (elapsed >= timeout_ms) {
errno = ETIMEDOUT;
return -1;
}
int remain = timeout_ms - elapsed;
if (wait_fd(
fd,
POLLIN,
remain
) < 0) {
return -1;
}
ssize_t n = recv(
fd,
buf + used,
sizeof(buf) - used - 1,
0
);
if (n > 0) {
used += (size_t)n;
buf[used] = '\0';
/*
* HTTP header complete
*/
if (strstr(buf, "\r\n\r\n") != NULL) {
/*
* Need:
*
* HTTP/1.1 200 Connection Established
*/
int code = 0;
if (sscanf(
buf,
"HTTP/%*s %d",
&code
) == 1) {
if (code >= 200 &&
code < 300) {
return 0;
}
errno = ECONNREFUSED;
return -1;
}
errno = EPROTO;
return -1;
}
continue;
}
if (n == 0) {
errno = ECONNRESET;
return -1;
}
if (errno == EINTR)
continue;
if (errno == EAGAIN ||
errno == EWOULDBLOCK) {
continue;
}
return -1;
}
errno = EOVERFLOW;
return -1;
}
/* ============================================================
* HTTP CONNECT Proxy
* ============================================================ */
static int proxy_connect(
const config_t *cfg
)
{
/*
* First connect to proxy.
*/
int fd = tcp_connect(
cfg->proxy_host,
cfg->proxy_port,
cfg->timeout_ms
);
if (fd < 0)
return -1;
/*
* Build CONNECT request.
*/
char request[4096];
int len;
if (cfg->proxy_auth) {
/*
* NOTE:
*
* This intentionally keeps the example simple.
* It expects credentials to be encoded separately
* if strict RFC-compliant Basic auth is required.
*/
char credentials[1024];
snprintf(
credentials,
sizeof(credentials),
"%s:%s",
cfg->proxy_user,
cfg->proxy_pass
);
/*
* Minimal base64 implementation.
*/
static const char table[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
unsigned char *src =
(unsigned char *)credentials;
size_t slen = strlen(credentials);
char encoded[2048];
size_t i;
size_t o = 0;
for (i = 0; i < slen; i += 3) {
unsigned int v = src[i] << 16;
if (i + 1 < slen)
v |= src[i + 1] << 8;
if (i + 2 < slen)
v |= src[i + 2];
encoded[o++] = table[(v >> 18) & 63];
encoded[o++] = table[(v >> 12) & 63];
if (i + 1 < slen)
encoded[o++] = table[(v >> 6) & 63];
else
encoded[o++] = '=';
if (i + 2 < slen)
encoded[o++] = table[v & 63];
else
encoded[o++] = '=';
}
encoded[o] = '\0';
len = snprintf(
request,
sizeof(request),
"CONNECT %s:%d HTTP/1.1\r\n"
"Host: %s:%d\r\n"
"Proxy-Authorization: Basic %s\r\n"
"Connection: keep-alive\r\n"
"\r\n",
cfg->host,
cfg->port,
cfg->host,
cfg->port,
encoded
);
} else {
len = snprintf(
request,
sizeof(request),
"CONNECT %s:%d HTTP/1.1\r\n"
"Host: %s:%d\r\n"
"Connection: keep-alive\r\n"
"\r\n",
cfg->host,
cfg->port,
cfg->host,
cfg->port
);
}
if (len <= 0 ||
len >= (int)sizeof(request)) {
close(fd);
errno = EINVAL;
return -1;
}
/*
* Send CONNECT.
*/
if (send_all(
fd,
request,
(size_t)len,
cfg->timeout_ms
) < 0) {
close(fd);
return -1;
}
/*
* Wait proxy response.
*/
if (proxy_read_response(
fd,
cfg->timeout_ms
) < 0) {
close(fd);
return -1;
}
/*
* Proxy tunnel established.
*/
return fd;
}
/* ============================================================
* Payload
* ============================================================ */
static int send_payload(
int fd,
int size,
int timeout_ms
)
{
if (size <= 0)
return 0;
unsigned char *payload =
malloc((size_t)size);
if (!payload)
return -1;
/*
* Fixed payload.
*
* This avoids random generation overhead.
*/
memset(
payload,
'A',
(size_t)size
);
int ret = send_all(
fd,
payload,
(size_t)size,
timeout_ms
);
free(payload);
return ret;
}
/* ============================================================
* Statistics
* ============================================================ */
static int cmp_double(
const void *a,
const void *b
)
{
double x = *(const double *)a;
double y = *(const double *)b;
if (x < y)
return -1;
if (x > y)
return 1;
return 0;
}
static void samples_add(
samples_t *s,
double value
)
{
if (s->count >= s->capacity) {
int new_capacity =
s->capacity == 0
? 1024
: s->capacity * 2;
if (new_capacity > MAX_SAMPLES)
new_capacity = MAX_SAMPLES;
if (new_capacity <= s->capacity)
return;
double *tmp = realloc(
s->values,
sizeof(double) *
(size_t)new_capacity
);
if (!tmp)
return;
s->values = tmp;
s->capacity = new_capacity;
}
s->values[s->count++] = value;
}
static double percentile(
samples_t *s,
double p
)
{
if (s->count == 0)
return 0.0;
double pos =
(p / 100.0) *
(double)(s->count - 1);
int index = (int)pos;
return s->values[index];
}
/* ============================================================
* Usage
* ============================================================ */
static void usage(const char *prog)
{
printf(
"\n"
"fasttcping - fast TCP ping with payload/proxy\n"
"\n"
"Usage:\n"
" %s [options] host port\n"
"\n"
"Options:\n"
" -c N probe count (default 4)\n"
" -i MS interval (default 1000)\n"
" -w MS timeout (default 1000)\n"
" -s BYTES payload size (default 0)\n"
" -P HOST:PORT HTTP proxy\n"
" -U USER proxy username\n"
" -W PASS proxy password\n"
" -h help\n"
"\n"
"Examples:\n"
" %s 10.0.0.1 443\n"
" %s -c 1000 -i 0 10.0.0.1 443\n"
" %s -s 64 10.0.0.1 443\n"
" %s -P 10.0.0.2:3128 10.0.0.1 443\n"
"\n",
prog,
prog,
prog,
prog,
prog
);
}
/* ============================================================
* Main
* ============================================================ */
int main(int argc, char **argv)
{
config_t cfg;
memset(&cfg, 0, sizeof(cfg));
cfg.count = DEFAULT_COUNT;
cfg.interval_ms = DEFAULT_INTERVAL;
cfg.timeout_ms = DEFAULT_TIMEOUT;
cfg.payload_size = 0;
int opt;
while ((opt = getopt(
argc,
argv,
"c:i:w:s:P:U:W:h"
)) != -1) {
switch (opt) {
case 'c':
cfg.count = atoi(optarg);
break;
case 'i':
cfg.interval_ms = atoi(optarg);
break;
case 'w':
cfg.timeout_ms = atoi(optarg);
break;
case 's':
cfg.payload_size = atoi(optarg);
break;
case 'P': {
cfg.use_proxy = 1;
char *colon =
strrchr(optarg, ':');
if (!colon) {
fprintf(
stderr,
"Invalid proxy: %s\n",
optarg
);
return 2;
}
size_t host_len =
(size_t)(colon - optarg);
if (host_len >=
sizeof(cfg.proxy_host)) {
return 2;
}
memcpy(
cfg.proxy_host,
optarg,
host_len
);
cfg.proxy_host[host_len] = '\0';
cfg.proxy_port =
atoi(colon + 1);
break;
}
case 'U':
snprintf(
cfg.proxy_user,
sizeof(cfg.proxy_user),
"%s",
optarg
);
cfg.proxy_auth = 1;
break;
case 'W':
snprintf(
cfg.proxy_pass,
sizeof(cfg.proxy_pass),
"%s",
optarg
);
cfg.proxy_auth = 1;
break;
case 'h':
usage(argv[0]);
return 0;
default:
usage(argv[0]);
return 2;
}
}
if (argc - optind < 2) {
usage(argv[0]);
return 2;
}
cfg.host = argv[optind];
cfg.port = atoi(argv[optind + 1]);
if (cfg.port < 1 ||
cfg.port > 65535) {
fprintf(
stderr,
"Invalid port\n"
);
return 2;
}
if (cfg.count <= 0)
cfg.count = 1;
if (cfg.timeout_ms <= 0)
cfg.timeout_ms = 1000;
if (cfg.interval_ms < 0)
cfg.interval_ms = 0;
if (cfg.payload_size < 0 ||
cfg.payload_size > MAX_PAYLOAD) {
fprintf(
stderr,
"Invalid payload size\n"
);
return 2;
}
printf(
"FASTTCPING %s:%d\n",
cfg.host,
cfg.port
);
if (cfg.use_proxy) {
printf(
"Proxy: %s:%d\n",
cfg.proxy_host,
cfg.proxy_port
);
}
printf(
"count=%d timeout=%dms interval=%dms payload=%d\n"
"\n",
cfg.count,
cfg.timeout_ms,
cfg.interval_ms,
cfg.payload_size
);
samples_t samples;
memset(&samples, 0, sizeof(samples));
int success = 0;
int failed = 0;
uint64_t total_start = now_us();
for (int seq = 1;
seq <= cfg.count;
seq++) {
uint64_t start = now_us();
int fd;
/*
* ====================================================
* Direct TCP
* ====================================================
*/
if (!cfg.use_proxy) {
fd = tcp_connect(
cfg.host,
cfg.port,
cfg.timeout_ms
);
}
/*
* ====================================================
* HTTP CONNECT Proxy
* ====================================================
*/
else {
fd = proxy_connect(&cfg);
}
if (fd < 0) {
failed++;
printf(
"[%d] FAILED error=%s\n",
seq,
strerror(errno)
);
} else {
/*
* TCP connect / proxy tunnel RTT
*/
double connect_ms =
(double)(now_us() - start)
/ 1000.0;
/*
* Optional payload.
*
* The payload is sent after the TCP
* connection is established.
*/
int payload_ret = 0;
if (cfg.payload_size > 0) {
payload_ret = send_payload(
fd,
cfg.payload_size,
cfg.timeout_ms
);
}
double total_ms =
(double)(now_us() - start)
/ 1000.0;
if (payload_ret < 0) {
failed++;
printf(
"[%d] PAYLOAD FAILED "
"connect=%.3f ms error=%s\n",
seq,
connect_ms,
strerror(errno)
);
} else {
success++;
samples_add(
&samples,
total_ms
);
if (cfg.payload_size > 0) {
printf(
"[%d] OK "
"connect=%.3f ms "
"payload=%d "
"total=%.3f ms\n",
seq,
connect_ms,
cfg.payload_size,
total_ms
);
} else {
printf(
"[%d] OK "
"time=%.3f ms\n",
seq,
total_ms
);
}
}
close(fd);
}
/*
* Interval
*/
if (seq < cfg.count &&
cfg.interval_ms > 0) {
sleep_ms(cfg.interval_ms);
}
}
uint64_t total_end = now_us();
printf(
"\n"
"--- FASTTCPING statistics ---\n"
);
printf(
"sent = %d\n",
cfg.count
);
printf(
"success = %d\n",
success
);
printf(
"failed = %d\n",
failed
);
printf(
"loss = %.2f%%\n",
cfg.count > 0
? 100.0 *
(double)failed /
(double)cfg.count
: 0.0
);
if (samples.count > 0) {
qsort(
samples.values,
(size_t)samples.count,
sizeof(double),
cmp_double
);
double min =
samples.values[0];
double max =
samples.values[samples.count - 1];
double sum = 0.0;
for (int i = 0;
i < samples.count;
i++) {
sum += samples.values[i];
}
double avg =
sum /
(double)samples.count;
printf(
"min = %.3f ms\n",
min
);
printf(
"avg = %.3f ms\n",
avg
);
printf(
"max = %.3f ms\n",
max
);
printf(
"p50 = %.3f ms\n",
percentile(&samples, 50.0)
);
printf(
"p95 = %.3f ms\n",
percentile(&samples, 95.0)
);
printf(
"p99 = %.3f ms\n",
percentile(&samples, 99.0)
);
}
printf(
"elapsed = %.3f sec\n",
(double)(total_end - total_start)
/ 1000000.0
);
free(samples.values);
return success > 0 ? 0 : 1;
}
./fasttcping -c 1000000 -i 0 -w 500 -s 64 10.252.16.68 443

#!/bin/bash
PCAP="pcap.pcap"
IP="$1"
PORT="$2"
# ============================================================
# 构造过滤条件
#
# 无参数:
# tcp
#
# IP:
# tcp && ip.addr == x.x.x.x
#
# IP + PORT:
# tcp && ip.addr == x.x.x.x && tcp.port == xxxx
# ============================================================
if [ -z "$IP" ]; then
FILTER="tcp"
SCOPE="GLOBAL"
elif [ -z "$PORT" ]; then
FILTER="tcp && ip.addr == $IP"
SCOPE="IP=$IP"
else
FILTER="tcp && ip.addr == $IP && tcp.port == $PORT"
SCOPE="IP=$IP PORT=$PORT"
fi
echo "===== TCP FLAG / RETRANSMISSION ANALYSIS ====="
echo "PCAP : $PCAP"
echo "SCOPE : $SCOPE"
echo "FILTER: $FILTER"
# ============================================================
# 基础 TCP 包数量
# ============================================================
total=$(tshark \
-r "$PCAP" \
-Y "$FILTER" \
2>/dev/null |
wc -l)
# ============================================================
# TCP FLAGS
# ============================================================
syn=$(tshark \
-r "$PCAP" \
-Y "$FILTER && tcp.flags.syn==1 && tcp.flags.ack==0" \
2>/dev/null |
wc -l)
syn_ack=$(tshark \
-r "$PCAP" \
-Y "$FILTER && tcp.flags.syn==1 && tcp.flags.ack==1" \
2>/dev/null |
wc -l)
fin=$(tshark \
-r "$PCAP" \
-Y "$FILTER && tcp.flags.fin==1" \
2>/dev/null |
wc -l)
rst=$(tshark \
-r "$PCAP" \
-Y "$FILTER && tcp.flags.reset==1" \
2>/dev/null |
wc -l)
ack=$(tshark \
-r "$PCAP" \
-Y "$FILTER && tcp.flags.ack==1 && tcp.len==0" \
2>/dev/null |
wc -l)
psh=$(tshark \
-r "$PCAP" \
-Y "$FILTER && tcp.flags.push==1" \
2>/dev/null |
wc -l)
# ============================================================
# TCP RELIABILITY
# ============================================================
retrans=$(tshark \
-r "$PCAP" \
-Y "$FILTER && tcp.analysis.retransmission" \
2>/dev/null |
wc -l)
dup_ack=$(tshark \
-r "$PCAP" \
-Y "$FILTER && tcp.analysis.duplicate_ack" \
2>/dev/null |
wc -l)
out_of_order=$(tshark \
-r "$PCAP" \
-Y "$FILTER && tcp.analysis.out_of_order" \
2>/dev/null |
wc -l)
lost_segment=$(tshark \
-r "$PCAP" \
-Y "$FILTER && tcp.analysis.lost_segment" \
2>/dev/null |
wc -l)
# ============================================================
# OUTPUT
# ============================================================
echo ""
echo "===== TCP PACKETS ====="
echo "Total TCP packets : $total"
echo "SYN : $syn"
echo "SYN-ACK : $syn_ack"
echo "FIN : $fin"
echo "RST : $rst"
echo "ACK (pure) : $ack"
echo "PSH : $psh"
echo ""
echo "===== RELIABILITY METRICS ====="
echo "Retransmissions : $retrans"
echo "Duplicate ACKs : $dup_ack"
echo "Out-of-order packets : $out_of_order"
echo "Lost segments : $lost_segment"
# ============================================================
# PERCENTAGE
# ============================================================
echo ""
echo "===== PERCENTAGE ====="
if [ "$total" -gt 0 ]; then
awk -v v="$syn" -v t="$total" \
'BEGIN {
printf "SYN %% : %.2f%%\n", v/t*100
}'
awk -v v="$fin" -v t="$total" \
'BEGIN {
printf "FIN %% : %.2f%%\n", v/t*100
}'
awk -v v="$rst" -v t="$total" \
'BEGIN {
printf "RST %% : %.2f%%\n", v/t*100
}'
awk -v v="$retrans" -v t="$total" \
'BEGIN {
printf "Retrans %% : %.2f%%\n", v/t*100
}'
awk -v v="$dup_ack" -v t="$total" \
'BEGIN {
printf "DupACK %% : %.2f%%\n", v/t*100
}'
else
echo "No TCP packets found."
fi
yum install -y wireshark-cli

| 字段 | 含义 | 常见产生原因 | 当前值判断 |
|---|---|---|---|
| Total TCP packets | 当前过滤条件下所有 TCP 数据包数量 | 正常 TCP 通信产生 | 7284,作为统计基数 |
| SYN | TCP 主动建立连接的请求包,SYN=1, ACK=0 |
客户端发起新 TCP 连接;短连接、高并发连接会增加 SYN | 28,正常 |
| SYN-ACK | 服务端对 SYN 的响应,SYN=1, ACK=1 |
服务端收到 SYN 后接受连接 | 28,与 SYN 基本对应,正常 |
| FIN | TCP 正常关闭连接 | 应用主动关闭连接、连接超时后的正常 FIN 流程 | 40,本身不能说明异常 |
| RST | TCP 强制终止连接 | 端口未监听、应用主动 reset、防火墙/LVS reset、TCP 状态异常、连接被强制关闭 | 28,需要进一步看 RST 是谁发送 |
| ACK (pure) | 只有 ACK、没有 TCP Payload 的确认包 | 确认收到数据、滑动窗口推进、TCP 控制流程 | 3165,正常 TCP 流量 |
| PSH | TCP 设置 PSH 标志,提示接收端尽快把数据交给应用层 | 发送应用数据时 TCP 设置 PSH;常见于交互式/请求响应流量 | 511,不是异常指标 |
| Retransmissions | Wireshark 判断某个 TCP Segment 被重新发送 | 网络丢包、拥塞、接收端 ACK 丢失、发送端超时、乱序触发快速重传等 | 14,较少 |
| Duplicate ACKs | 接收端重复确认相同 ACK/Sequence | 前面的 TCP Segment 未到达、乱序、ACK 重复到达/抓包异常 | 8,较少 |
| Out-of-order packets | TCP Segment 到达顺序与 Sequence Number 顺序不一致 | 网络路径变化、多路径、链路重排、队列调度、抓包点造成的顺序变化 | 3,较少 |
| Lost segments | Wireshark 根据 TCP Sequence Number 判断中间可能缺少 Segment | 真实丢包、抓包丢包、capture point 不完整、接口 offload 等 | 17,需要结合实际抓包判断 |
浙公网安备 33010602011771号