Java Socket手写邮件客户端:SMTP/POP3协议与网络组建实验全解析
简介这份资源是华中科技大学计算机科学与技术专业的计算机网络课程实验报告面向正在学习计算机网络、需要完成Socket编程与网络组建实验的高校学生。报告以docx文档形式呈现压缩包内共1个文件大小约3.67MB内容结构完整包含实验目的、要求、内容、过程与体会等标准章节。报告涵盖两大部分一是基于Java Socket的E-Mail编程实验涉及TCP/UDP Socket分类、客户端-服务器架构、SMTP与POP3等邮件协议并给出需求分析、界面设计、写信与收信的实现过程二是网络组建与实施实验包含组网、路由配置、VLAN划分及访问控制配置四个子实验涉及网络拓扑结构、路由器与交换机等设备配置及网络测试方法。目前已有427人学习适合作为课程实验参考与期末复习资料帮助读者理解网络通信编程与组网配置的关键步骤。1. 从一份 2013 年的华科实验报告说起Java Socket 手写邮件客户端到底能跑通什么翻到这份《华科-计算机网络实验报告-Java_Socket编程-网络组建实验.docx》的时候我第一反应是这不是那种交完就删的课程作业而是一份把应用层协议从零拆到字节流的完整记录。它用 Java 的Socket类直接怼 SMTP 和 POP3 服务器不借助JavaMail这类现成组件硬生生把一封邮件的发送、接收、下载、删除全流程走了一遍。对正在啃 socket 网络编程、准备 java 面试题里“TCP 三次握手怎么落到代码”这类问题的同学来说这份报告的价值不在于界面多漂亮而在于它把EHLO、AUTH LOGIN、MAIL FROM、RCPT TO、DATA这些命令和服务器返回码一行行打印出来让你看见协议是怎么呼吸的。它适合两类人一是刚学完计算机网络、想找个能跑通的 demo 把理论焊死在代码上的学生二是需要快速回顾 Java 原生 Socket 操作、不想被框架封装遮住眼睛的开发者。下面我就按“这份资源是什么、怎么复现、坑在哪”的顺序把它拆开讲透。2. 把 SMTP 会话拆成命令行SendAction 里每一行代码在跟服务器说什么2.1 为什么不用 JavaMail 而坚持裸写 Socket这份报告在实验要求里写得很死“必须基于 Socket 编程不能直接借用任何现成的组件。” 这条约束恰恰是它最值得看的地方。JavaMail把Session、Transport、Store封装得太好好到你写完Transport.send(message)就结束了根本不知道背后发了什么。而裸写 Socket 意味着你要自己拼邮件报文、自己处理 Base64 编码、自己读服务器应答。常见做法是先用telnet连一下邮件服务器的 25 端口手动敲一遍EHLO、AUTH LOGIN看服务器怎么回再把这一串交互翻译成 Java 代码。报告里SendAction函数就是这么干的它把发件人、收件人、主题、正文拼成一个字符串然后通过PrintWriter一行行推给服务器。这种写法在 2024 年看确实原始但对于理解 SMTP 是“基于文本行的请求-响应协议”这件事没有比它更直接的了。2.2 SendAction 的完整调用链与参数含义先看类里的数据结构这是后面所有操作的输入源public class SendFrame extends JInternalFrame { private JTextField txt_to; // 收件人地址输入框 private JTextField txt_subject; // 主题输入框 private JTextArea textArea; // 正文输入区 private String pusernameadd; // 当前用户完整邮件地址如 xxx163.com private String ppasswd; // 邮箱密码或授权码 private String psn_s_smtp; // SMTP 服务器地址如 smtp.163.com private String pusername1; // 用户名不含 后缀 }这些字段在构造函数SendFrame里从登录界面传进来赋值后一直挂在对象上。当用户点击 Send 按钮btnNewButton.addActionListener触发调用SendAction(txt_to.getText(), textArea.getText(), txt_subject.getText())。注意参数顺序收件人、正文、主题——这个顺序和界面上从上到下的排列不一致写代码时如果按界面顺序传参主题和正文就会互换这是第一个容易翻车的地方。SendAction内部的核心逻辑分四步。第一步拼报文mailContent From: from \n To: to \n Subject: subject1 \n Constent: constent1 \n;这里有个明显的笔误Constent应该是Content但 SMTP 协议本身不校验头部字段名服务器只认From、To、Subject这些标准字段Constent会被当作自定义头忽略掉正文实际上是通过后面的DATA段单独发送的。所以这个拼写错误不影响功能但会让你在抓包时困惑一下。第二步建立连接并读取欢迎语String hostName InetAddress.getLocalHost().getHostName(); Socket s new Socket(mailServer, 25); BufferedReader inFromServer new BufferedReader( new InputStreamReader(s.getInputStream())); PrintWriter outToServer new PrintWriter(s.getOutputStream(), true); response inFromServer.readLine(); System.out.print(MailServer: response \n);new Socket(mailServer, 25)这行代码背后是 TCP 三次握手连上之后服务器会主动推一行220开头的欢迎语。PrintWriter的第二个参数true表示自动 flush少了它你会发现在readLine()那里卡死——因为数据还在缓冲区里没发出去。第三步身份验证这是最容易出问题的地方BASE64Encoder encoder new BASE64Encoder(); String encodedUser encoder.encode(pusername1.getBytes()); String encodedPwd encoder.encode(ppasswd.getBytes()); outToServer.println(EHLO hostName); for (int i 0; i 5; i) { response inFromServer.readLine(); System.out.print(MailServer: response \n); } outToServer.println(AUTH LOGIN ); response inFromServer.readLine(); outToServer.println(encodedUser); response inFromServer.readLine(); outToServer.println(encodedPwd); response inFromServer.readLine();EHLO之后服务器会返回多行应答报告里硬编码读 5 行这个数字因服务器而异。163 邮箱通常返回 5 行左右但 Gmail 可能更多。如果读少了后面的AUTH LOGIN应答就会错位读多了readLine()会阻塞。稳妥的做法是循环读到某行以空格开头多行应答的续行标志或者直接判断返回码。AUTH LOGIN之后服务器分别要用户名和密码的 Base64 编码注意这里用的是pusername1不含 的用户名而不是完整地址用错了会返回535认证失败。第四步发信并断开outToServer.println(MAIL FROM: from ); response inFromServer.readLine(); outToServer.println(RCPT TO: to ); response inFromServer.readLine(); outToServer.println(DATA); response inFromServer.readLine(); outToServer.println(mailContent); outToServer.println(.); response inFromServer.readLine(); s.close();MAIL FROM和RCPT TO后面必须跟尖括号包裹的地址这是 RFC 5321 的规定。DATA之后服务器返回354然后你发送正文最后用一个单独的点号.表示结束。报告里outToServer.println(mailContent)出现了两次这是重复发送正文的 bug会导致邮件内容翻倍。正确做法是只发一次然后紧跟一个.。2.3 参数怎么改、失败时看什么如果你要拿这份代码去连自己的邮箱需要改三个地方psn_s_smtp改成你的 SMTP 服务器地址163 是smtp.163.comQQ 是smtp.qq.compusernameadd改成完整邮件地址ppasswd改成授权码而不是登录密码。现在主流邮箱都要求用授权码直接用密码会返回535。端口方面25 端口在很多网络环境下被运营商封了可以试 465SSL或 587STARTTLS但这份代码没有实现 SSL 层所以只能跑 25 端口这是它的时代局限。失败时优先看控制台打印的MailServer:那几行。220是连接成功250是命令接受334是等待 Base64 输入235是认证成功354是开始发正文221是断开。如果卡在某个readLine()不动八成是上一条命令发出去后服务器没给预期响应用telnet手动复现一遍就能定位。3. POP3 收信与邮件列表渲染GetMail 怎么把服务器邮件拉进 JTable3.1 POP3 的三种状态与 getsubmaillist 的取头逻辑收信部分由GetMail和POP3Client两个类协作完成。GetMail负责界面和邮件列表展示POP3Client负责跟服务器对话。POP3 协议分三个阶段授权USER/PASS、事务STAT、LIST、RETR、DELE、更新QUIT。报告里的getsubmaillist()函数对应事务阶段的TOP命令只拉取邮件头信息public void getsubmaillist() throws Exception { POP3Client pop3 new POP3Client(get_server, get_username, get_passwd); pop3.connect(); int mailCount pop3.getMailCount(); submaillist new String[mailCount]; for (int i 1; i mailCount; i) { String header pop3.getMailHeader(i); submaillist[i - 1] header; } pop3.disconnect(); }getMailCount()内部发的是STAT命令服务器返回OK 3 12345表示有 3 封邮件、总大小 12345 字节。getMailHeader(i)发的是TOP i 0只取第 i 封邮件的头部不取正文。这样做的目的是快速列出收件箱避免一次性下载所有邮件正文导致界面卡死。报告里maillist是一个String[20][3]的二维数组分别存标题、发件人、时间从头部信息里解析出来填进去。3.2 JTable 的数据绑定与 Show 按钮的事件传递GetMail的构造函数里getsubmaillist()和getmaillist()被依次调用然后把maillist数组直接塞给JTableObject[] columnTitle {Title, From, Time}; table new JTable(maillist, columnTitle); table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); table.setBounds(14, 44, 804, 366); contentPane.add(table.getTableHeader()); contentPane.add(table);JTable用二维数组构造时第一维是行第二维是列列的顺序必须和columnTitle一一对应。报告里maillist[a][2]存的是时间maillist[a][1]存的是发件人maillist[a][0]存的是标题但在Show按钮的事件里传参顺序是new ShowMail(maillist[a][2], maillist[a][1], maillist[a][0], ...)也就是时间、发件人、标题。如果ShowMail构造函数按标题、发件人、时间的顺序接收这里就会错位。这是第二个容易翻车的地方建议在传参前先打印一下数组内容确认。Show按钮的完整逻辑btnShow.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int[] selected table.getSelectedRows(); int a selected[0]; DESKTOP_PANE.add(new ShowMail( maillist[a][2], maillist[a][1], maillist[a][0], getmailcontent(a 1), DESKTOP_PANE, get_usernamelong, get_passwd, get_username, get_smtp, get_server)); } });getSelectedRows()返回选中行的索引数组selected[0]取第一行。getmailcontent(a 1)发的是RETR a1把第 a1 封邮件的完整内容拉下来。注意 POP3 的邮件编号从 1 开始而数组索引从 0 开始所以这里要加 1。3.3 DownloadAll 与 DownloadDelete 的差异报告里还有两个按钮DownloadAll和DownloadDelete。前者循环调用RETR把所有邮件保存到本地文件后者在保存之后额外发一个DELE命令标记删除最后QUIT时服务器才真正删除。DELE只是打标记如果在QUIT之前断开连接删除不会生效。这个机制是 POP3 的“后悔药”但报告里没有实现异常回滚如果保存文件时抛了IOExceptionDELE已经发出去了邮件就真没了。稳妥的做法是先全部RETR并写文件成功再统一发DELE。4. 网络组建实验的配置逻辑从 VLAN 划分到访问控制列表4.1 实验环境与拓扑搭建的先后顺序报告的第二部分“网络组建与实施”覆盖了四个子实验组网、路由配置、VLAN 划分、访问控制配置。实验环境通常是 Cisco Packet Tracer 或真实交换机路由器。组网实验要求把 PC、交换机、路由器按指定拓扑连起来配置 IP 地址和子网掩码验证同网段互通。路由配置实验要求配置静态路由或 RIP让不同网段互通。VLAN 划分实验要求在同一台交换机上创建多个 VLAN把端口划分进去验证广播域隔离。访问控制实验要求用 ACL 限制特定流量。这四个实验有严格的依赖顺序先组网通物理层和数据链路层再配路由通网络层再划 VLAN 隔离广播域最后用 ACL 做安全策略。如果顺序反了比如先配 ACL 再划 VLANACL 绑定的接口可能因为 VLAN 变更而失效。报告里 2.4.2 到 2.4.5 的节次安排就是这个顺序照着做不会乱。4.2 VLAN 划分的关键命令与验证方法以 Cisco 交换机为例创建 VLAN 并划分端口的典型配置Switch enable Switch# configure terminal Switch(config)# vlan 10 Switch(config-vlan)# name IT Switch(config-vlan)# exit Switch(config)# vlan 20 Switch(config-vlan)# name HR Switch(config-vlan)# exit Switch(config)# interface fastEthernet 0/1 Switch(config-if)# switchport mode access Switch(config-if)# switchport access vlan 10 Switch(config-if)# exit Switch(config)# interface fastEthernet 0/2 Switch(config-if)# switchport mode access Switch(config-if)# switchport access vlan 20 Switch(config-if)# end Switch# show vlan briefswitchport mode access把端口设为接入模式switchport access vlan 10把它划进 VLAN 10。验证时用show vlan brief看端口归属然后在同一 VLAN 的两台 PC 之间 ping 通不同 VLAN 的 PC 之间 ping 不通。如果不同 VLAN 能 ping 通说明端口没划对或者交换机之间跑了 VTP 把 VLAN 配置同步乱了。4.3 访问控制列表的匹配顺序与常见误配ACL 的规则是从上往下匹配一旦匹配就执行动作不再往下看。所以拒绝规则要放在允许规则前面。一个典型的扩展 ACLSwitch(config)# access-list 100 deny tcp 192.168.10.0 0.0.0.255 192.168.20.0 0.0.0.255 eq 80 Switch(config)# access-list 100 permit ip any any Switch(config)# interface fastEthernet 0/24 Switch(config-if)# ip access-group 100 indeny tcp拒绝 VLAN 10 访问 VLAN 20 的 80 端口permit ip any any放行其他所有流量。最后一行ip access-group 100 in把 ACL 应用到接口的入方向。常见误配是忘了最后的permit导致所有流量被隐式拒绝整个网络不通。另一个坑是 ACL 应用方向搞反in是进入接口的流量out是离开接口的流量配错了规则不生效。5. 避坑与排查这份 2013 年的代码放到今天跑要注意什么5.1 现象连接 25 端口超时控制台没有任何输出原因现在绝大多数云服务器和家庭宽带都封了 25 端口的出站流量防止垃圾邮件。报告写于 2013 年当时 25 端口还能随便用。解决换用 465 或 587 端口但这份代码没有实现 SSL/TLS直接改端口号会连上但无法完成AUTH LOGIN。要么补上SSLSocketFactory的代码要么用本地搭建的邮件服务器如 hMailServer在局域网内测试。5.2 现象AUTH LOGIN之后返回535 Authentication failed原因用了邮箱登录密码而不是授权码。163、QQ、Gmail 从 2022 年起全面要求第三方客户端使用授权码。解决登录网页邮箱在设置里开启 SMTP/POP3 服务并生成授权码把ppasswd换成授权码。注意授权码是 16 位字符串不要带空格。5.3 现象EHLO之后readLine()阻塞程序卡死原因报告里硬编码读 5 行应答但不同邮件服务器返回的行数不同。163 可能返回 5 行QQ 返回 6 行Gmail 返回 4 行。读少了后面的命令错位读多了阻塞。解决改成循环读取判断每行是否以空格开头多行应答的续行或者读到返回码后跟空格的行停止。示例String line; while ((line inFromServer.readLine()) ! null) { System.out.println(MailServer: line); if (line.length() 4 line.charAt(3) ) { break; } }5.4 现象邮件发送成功但正文为空或重复原因报告里outToServer.println(mailContent)写了两次导致正文重复。另外mailContent里用了Constent而不是Content虽然不影响发送但会让头部多一个无效字段。解决删掉重复的那行println把Constent改成Content。正文应该只在DATA之后发送一次然后紧跟一个单独的点号。5.5 现象BASE64Encoder编译报错提示找不到符号原因sun.misc.BASE64Encoder是 JDK 内部类从 JDK 9 开始被移除JDK 11 之后完全不可用。解决换成java.util.Base64String encodedUser Base64.getEncoder().encodeToString(pusername1.getBytes()); String encodedPwd Base64.getEncoder().encodeToString(ppasswd.getBytes());注意Base64.getEncoder()默认不加换行而sun.misc版本每 76 个字符加一个换行。SMTP 的AUTH LOGIN对换行不敏感但如果你发现认证失败可以试Base64.getMimeEncoder()。6. 进阶玩法把这份报告改成可配置的邮件客户端并验证协议交互如果你已经跑通了基本流程下一步可以把硬编码的参数抽成配置文件让程序支持多邮箱切换。我一般会在项目根目录放一个mail.propertiessmtp.serversmtp.163.com smtp.port25 pop3.serverpop3.163.com pop3.port110 usernameyourname passwordyour_auth_code fromyourname163.com然后在 Java 里用Properties加载Properties props new Properties(); try (InputStream in new FileInputStream(mail.properties)) { props.load(in); } String smtpServer props.getProperty(smtp.server); int smtpPort Integer.parseInt(props.getProperty(smtp.port));这样换邮箱只需要改配置文件不用重新编译。更进一步可以把SendAction和POP3Client里的System.out.print换成日志框架把每次会话的请求和响应写到文件里方便事后排查。我习惯在readLine()之后加一行logger.debug(S: response)在println()之前加一行logger.debug(C: command)这样抓出来的日志和 Wireshark 抓包能对上。验证协议交互是否正确的终极方法是同时开 Wireshark 抓包过滤tcp.port 25看 Java 程序发出的每一行和服务器返回的每一行是否和日志一致。如果日志里有但抓包没有说明PrintWriter没 flush如果抓包有但日志没有说明readLine()读到了空行或者阻塞了。这个对照过程能帮你把 Socket 编程里“发送”和“接收”的边界彻底搞清楚。从那以后我每次写 Socket 相关的代码都会强制走一遍“先 telnet 手动敲、再写代码、最后抓包对照”的流程少一步都可能被玄学问题卡半天。希望这份拆解能帮到你。本文还有配套的精品资源点击获取

相关新闻

Java并发编程:start()与run()的区别,从源码到实战一次讲透

Java并发编程:start()与run()的区别,从源码到实战一次讲透

Java并发编程系列写到第3篇,我想把两个几乎人人都会见到、但一半人说不清区别的方法单独拎出来聊一聊:start()和run()。说实话,我在不少团队做过代码评审,看到过太多类似new Thread(() -> {...}).run()的写法——写的人觉得自己…

2026/10/14 4:36:57 阅读更多 →
办公用品直售推荐系统:SpringBoot+Vue企业级实现

办公用品直售推荐系统:SpringBoot+Vue企业级实现

企业办公用品做直售,还要带推荐系统,这个需求放在两年前我大概率会劝对方别折腾,直接套一套电商开源框架改改算了。但真把需求聊透之后会发现,办公用品采购和普通电商完全是两回事:下单的人不一定是用东西的人&#xf…

2026/10/10 4:26:03 阅读更多 →
膳食营养健康网站:SpringBoot+Vue前后端分离设计与实现

膳食营养健康网站:SpringBoot+Vue前后端分离设计与实现

我做毕业设计的时候选了膳食营养健康网站这个方向,最初的想法很简单:现在大家越来越关注吃得好不好、吃得健不健康,做一个能查食物营养、能记录饮食、能给出合理建议的网站,既有实际意义,也适合用来练习完整的全栈开发…

2026/10/10 6:09:53 阅读更多 →

最新新闻

计及需求侧响应的配电网供电能力综合评估Matlab实现

计及需求侧响应的配电网供电能力综合评估Matlab实现

供电能力评估这个方向,做配电网规划的人都不陌生。传统做法很简单:把负荷当成一个给定的“硬条件”,算主变、算线路、算N-1通过率,能带多少就是多少。但问题是,现在的负荷已经不再“硬”了——分时电价、可中断负荷、车…

2026/10/14 6:02:23 阅读更多 →
AI协作者实战指南:从提示词工程师到流程编排师

AI协作者实战指南:从提示词工程师到流程编排师

1. 这不是“自动印钞机”,而是AI时代的职业重构现场“自动赚钱时代来了?”——这个标题一出来,朋友圈就炸了。有人截图转发配文“终于等到这一天”,也有人冷笑评论“又一个割韭菜的标题党”。但真正让我坐下来认真拆解它的&#x…

2026/10/14 6:02:23 阅读更多 →
ZeroTermux 内置命令手册:tcpreplay 报文重放与双网卡网络测试实战

ZeroTermux 内置命令手册:tcpreplay 报文重放与双网卡网络测试实战

移动开发开发工具 【免费下载链接】ZeroTermux 项目地址: https://gitcode.com/GitHub_Trending/ze/ZeroTermux 点击查看 免费下载 导读 tcpreplay 是一款基于 PCAP 文件的报文重放工具,它能把用 Wireshark(及其前身 Ethereal)、…

2026/10/14 6:02:23 阅读更多 →
AnyPS5:一套对任意PS5都适用的折腾与优化方案

AnyPS5:一套对任意PS5都适用的折腾与优化方案

看到“AnyPS5”这个名字,估计不少人会误会:是破解方案?是某个新机型?其实都不是。我更愿意把它理解为一套“对任意一台PS5都适用的折腾与优化方案”。这些年帮朋友处理过不少台PS5主机,有的是刚拆封的新机,…

2026/10/14 6:02:23 阅读更多 →
轻资产酒店集团财报解读:现金流、分红与CFO变动背后的逻辑

轻资产酒店集团财报解读:现金流、分红与CFO变动背后的逻辑

最近酒店行业的头条,大概率是这家头部连锁酒店集团的年度成绩单:营收253亿,净利51亿,同时宣布派发约4亿美元股息,同一时间,任职多年的CFO卸任。几个消息堆在一起,很多人第一反应是"业绩不错…

2026/10/14 6:02:23 阅读更多 →
高校农业病虫害智能监测系统设计与实现

高校农业病虫害智能监测系统设计与实现

1. 项目概述农业病虫害监测与预测一直是农业生产中的关键环节。传统的人工巡查方式效率低下且容易遗漏,而基于大数据的智能监测系统正在改变这一现状。这个项目构建了一个面向高校场景的农业病虫害监测与趋势预测系统,整合了数据采集、存储、分析和可视化…

2026/10/14 6:01:22 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →