96SEO 2026-08-02 01:42 1
这是整个系列最复杂的一篇,也是 WeakNet 最主要的部分。

前面几篇我们讲了 VpnService 怎么把流量导入使用者态、怎么从原始字节解析出 IP/TCP/UDP 头部。这些都只是准备工作,真正的难题是:拿到 App 发出的 TCP 数据包之后怎么办?其实,
TCP 是一个有状态的、可靠的、字节流协议。它有连接建立、连接关闭、管理、超时重传、流量控制、拥塞控制等一整套复杂的机制。正常情况下这些由操作程序内核的 TCP/IP 协议栈完成。而 WeakNet 要做的事情。是在使用者态重新实现一个 TCP 端点——代理既是 App 的"服务器",又是真实服务器的"客户端"。你需要自己管理 seq/ack、自己处理 SYN 和 FIN、自己决定什么时候发 ACK、什么时候该让包"丢掉"。
说白了这不是简单的代理转发——你在使用者态实现了一个完整的 TCP 端点。按理说,
理解 WeakNet 的 TCP 代理,最关键的一点是:代理进程维护了两条独立的 TCP 连接。
App <-- TCP --> 代理 <-- TCP --> 真实服务器 App 认为在跟服务器通信 代理建立真实连接 是跟代理通信 转发 App 的数据到服务器
App 发出的 TCP 包经过 TUN 接口到达 PacketProcessor。PacketProcessor 解析 TCP 头部,根据四元组查找或创建一个 TcpSession。对于 App 代理就是"服务器";对于真实服务器代理,说白了就是"客户端"。两边各自维护独立的 seq/ack,互不感知。
这个模型代表着:
TcpSession -> 代理模拟 SYN-ACK 给 App -> 代理在后台连接真实服务器收到 App 发来的 SYN 包时代理需要做三件事:创建会话、模拟 SYN-ACK、连接真实服务器。话说回来,其中模拟 SYN-ACK 是关键——它让 App 以为连接已经建立。可以开始发数据了,
// 收到 SYN 包
if {
// 同一四元组已有未关闭会话,丢弃重复 SYN
if return
val session = tcpSessionManager.createSession(
ip.sourceAddress,tcp.sourcePort,ip.destinationAddress,tcp.destinationPort,tcp.sequenceNumber)
// 随机初始 seq,模拟真实服务器的初始
session.serverSeq = Random.nextInt
// 必须在后台线程:先给 app 发 SYN-ACK,再阻塞等真实连接
connectExecutor.submit {
// . SYN-ACK 也要经过延迟。模拟真实网络的握手 RTT
val jitter = pipeline.calculateJitter
val synDelay = .coerceAtLeast.toLong
if Thread.sleep
sendSynAck // 内部已调用 addAndGetServerSeq,// SYN 占 个 seq 号
// . 建立真实 TCP 连接
if ) {
// . 把握手期间 app 缓存的数据发给真实服务器
val pendingWriteData = pendingData.remove
if {
synchronized {
val wbuf = ByteBuffer.wrap
while ) {
session.channel?.write
}
}
}
// . 进入 relay 循环
relayUpstream
} else {
// 连不上就直接 RST。让 app 快速失败
sendRstToSession
tcpSessionManager.removeSession
}
}
return
}
private fun sendSynAck {
val tcpHeaderLen = /* 基础长度 + 长度 */
val pkt = ByteArray + TCP */)
/* ...IP头... */
// TCP Options:
// MSS=
// NOP + Window Scale=
// Window=
session.addAndGetServerSeq // SYN 占 个 seq
updateTcpChecksum
writeToTun
}
enum class TcpState {SYN_RECEIVED。ESTABLISHED,CLOSED}
class TcpSession {
private val _state = AtomicReference
fun connectBlocking: Boolean {
val ch = SocketChannel.open
ch.configureBlocking
if )) { ch.close;return false }
ch.socket.connect,timeoutMs)
_channel.set
if ) {
try { ch.close } catch {}
return false
}
return true
}
fun close {
if == TcpState.CLOSED) return
try { _channel.getAndSet?.close } catch {}
}
}
// 在 ACK 前决定是否丢包
val tcpLost = pipeline.shouldDropTcpOutgoing
if {
session.clientNextSeq = newSeqEnd
sendAck
}
outgoingExecutor.submit{
ifreturn@submit
val manipulated=pipeline.processOutgoing
/* 写到上游 SocketChannel…话说回来,*/
}
// 使用无符号比较防止 seq 回绕误判
val newSeqEnd=tcp.sequenceNumber+payloadSize
if and0xFFFFFFFFL)<=
and0xFFFFFFFFL)) return
// channel 未就绪时缓冲等待连接建立 pendingData.compute
...
// relayUpstream // 每次读取 MTU - IP头 -TCP头 字节数以内,以保证构造出的 IP 包恰好不超过 MTU.
private fun relayUpstream{ val buf=ByteBuffer.allocate val ch=session.channel?:return while { buf.clear;var bytesRead=ch.read;... }
MTU - IP头 -TCP头,否则构造出的 IP 包将被分片;每个分片都需要单独处理和校验。bytesRead 字节就要加上去,而不是简单地 ++。RST 处理最简单:直接清理会话,不走操控管线。RST 是“异常断开”,应该尽快生效,被延迟反而会导致问题。
FIN 处理要复杂一些。FIN 可能携带最终一批数据,而且要保证 FIN 在所有排队数据之后处理。FIN 整个提交到 outgoingExecutor
kotlin
if {
outoingExecutor.submit{
...
private fun sendRstToSession{ ... }
如前面讨论。当 CAS 操作失败表示已有其它线程关闭了该 Session,但此时我们还没创建 socket 或刚刚创建完成。一定要显式地 close 那个 socket,以防长期运行后文件描述符耗尽。
TCP 是流协议。如果每个包都 sleep,那么第 N 个包往往比理论 RTT 多 N×sleep 时间!只在握手阶段施加人工延迟,在真正的数据传输阶段使用限速或流水线调度。而不是每个 packet sleep。
| 阶段 | 主要操作 | 常见坑 |
|---|---|---|
| 接收SYN | 模拟SYN‑ACK 开启后台 connect | 未及时返回 ACK → 握手机能卡住 |
| 建立通道 | CAS 控制状态转换 及时关闭 fd | CAS 未成功却忘记 close → FD 泄漏 |
| 出方向转发 | pre‑ACK 丢包 无符号 seq 比较 | ack/seq 溢出/回绕 |
| 入方向转发 | 按 MTU 分块 按字节递增 seq | 粘包 / 冗余分片 |
| FIN/RST | 按 RFC 构造报文 资源顺序正确 | RST 未带 ACK → 被忽略 |
既然已经搞定了从 SYN→ESTABLISHED→CLOSE` 全生命周期,只剩下真正操控- 数据包装器这一块可以继续:
敬请期待下一篇《弱网效果管线设计》!话说回来,
项目地址: https://github.com/baithinking…
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback