简介:smb.rar_SMB 是一份以经典《超级玛丽》(Super Mario Bros)为蓝本的 2D 平台游戏源码工程,面向刚接触游戏编程的 C 语言学习者和爱好者,演示了从窗口创建、资源加载到游戏逻辑更新的完整流程。压缩包内共 33 个文件,约 58KB,包含 4 个 .c 源码与 10 个 .h 头文件、10 个 .pcx 图片资源、4 个 .dat 关卡数据,以及 .dpr/.prj/.dsk 工程文件和可直接运行的 EXE;其中头文件用于模块接口声明,PCX 提供角色与背景贴图,DAT 存储地图布局,便于按模块对照阅读,整体体量轻量,适合短时间通读。项目依赖 DirectX SDK 与 GLUT(glut32.dll/glut.lib),可借此熟悉 2D 图形渲染、窗口构建和键盘输入处理。源码涉及角色动画、碰撞检测、关卡设计与游戏主循环等核心逻辑,是拆解经典平台动作游戏设计思路的实用范例。目前已有 121 人学习下载,适合想要理解早期游戏工程结构、提升 C 语言与图形编程能力的开发者。
1. SMB 文件共享协议:为什么局域网共享动不动就失败
SMB 是 Windows 局域网共享文件的核心协议,几乎每一次"找不到网络路径""凭据不满足""能 ping 通却连不上"的报错,最终都要回到 SMB 的版本协商、服务状态和防火墙设置上。方向大家都清楚,但真正动手时,多数人卡在三个地方:不知道目标机用的是 SMB1 还是 SMB3、网络发现服务没拉起、guest 账户压根不是该折腾的点。这篇笔记把 SMB 的选型、Windows 10 共享配置、凭据模型和故障排查按顺序拆开,适合运维、网管、搭 NAS 或经常在两台 Windows 之间倒文件的人对照着操作。配合这份 smb.rar 里的配置命令和错误码对照,能少走很多弯路。
2. SMB 版本选型:三版差异与网关兼容性边界
2.1 SMB1/2/3 到底差在哪
SMB 协议从 1987 年的 SMB1(CIFS)一路演进到 SMB3.1.1,版本差异不是简单的数字大小,而是直接影响你能不能连上、连上之后安不安全。
| 版本 | 常见系统 | 默认端口 | 安全特性 | 现状 |
|---|---|---|---|---|
| SMB1 | Windows XP / 2003、老 NAS、部分光猫 | 139 + 445 | 明文传输、无签名 | 默认禁用 |
| SMB2 | Windows 7 / Server 2008 R2 | 445 | 支持复合请求 | 可启用 |
| SMB2.1 | Windows 7 后期版本 | 445 | 引入耐久句柄 | 可启用 |
| SMB3 / 3.0.2 | Windows 8 / Server 2012 | 445 | 加密、多通道、故障转移 | 推荐 |
| SMB3.1.1 | Windows 10 / Server 2016+ | 445 | AES-128 加密、预认证完整性 | 推荐 |
SMB1 之所以要禁用,除了性能差,更关键的是它不支持签名和加密,WannaCry 就是借道 SMB1 漏洞传播的。而 SMB3 以后,加密和数据完整性校验成了内建能力,跨公网或不可信网段传文件时,安全性不是一个量级。
我在实际配置里的一般做法是:Windows 10 及以上系统全部走 SMB3,只有遇到老 NAS、老打印机或特殊设备时才临时开 SMB1,用完立刻关,不给内网留一个明文的洞。
2.2 天翼网关这类设备的 SMB 兼容坑
家宽光猫(天翼网关)自带的 USB 共享功能,底层就是 SMB 服务。这类嵌入式设备的通病是固件版本老,SMB 实现往往只支持 SMB1 或最多到 SMB2.0。这就产生一个很现实的问题:Windows 10 默认关闭 SMB1,你拿着开了 SMB3 的电脑去访问光猫的共享目录,结果是能 ping 通设备、能访问网关管理页,但 \192.168.1.1\usb 这个路径永远提示找不到网络路径。
遇到这种情况,先确认光猫的 SMB 服务版本。登录网关管理页看 USB 存储设置,一般会标注"启用 SMB 文件共享"或"SMB1 兼容模式"。如果只有 SMB1 选项,Windows 侧的临时解法是:
# 以管理员身份运行 PowerShell,临时启用 SMB1 协议 Set-SmbServerConfiguration -EnableSMB1Protocol $true逻辑说明:Set-SmbServerConfiguration 修改的是本机 SMB 服务端的协议支持范围,$true 表示允许本机作为服务端接受 SMB1 客户端连接,同时本机作为客户端去访问老设备时也需要对应协议栈支持,所以同一命令同时影响出入两个方向。参数 EnableSMB1Protocol 在 Windows 10 上默认是 $false,改成 $true 后不需要重启,立即生效。
注意,启用 SMB1 之后,本机的安全基线会下降,我一般只在访问光猫或老 NAS 时临时打开,验证完就关回去。正规做法是找光猫的固件升级或换用支持 SMB2 以上的设备,别让一台网关把整网的安全等级拉低。
2.3 一条命令确认当前协商版本
判断两台机器实际用的是哪个 SMB 版本,比看配置更直接的办法是看协商结果。Windows 10 上执行:
Get-SmbConnection输出中重点看 ServerName(对方主机)、ShareName(共享名)、Dialect(协商出的协议方言)。Dialect 显示 3.1.1 说明走的 SMB3.1.1,显示 2.0.2 说明退回到了 SMB2.0,如果显示 1.0 那就得注意了。
这里有个容易踩的误区:Get-SmbConnection 只能看到当前活跃的连接。如果你之前用 \192.168.1.10 访问过并保持连接,改完协议配置后需要先断开再重连,不然看到的还是旧协商结果。断开命令:
# 清掉目标机的所有 SMB 会话,然后再重新访问 net use \\192.168.1.10 /deletenet use 的 /delete 参数指定删除与 192.168.1.10 的所有连接,删除干净了再重新访问,Get-SmbConnection 才会显示新协商的 Dialect 版本。这一步是排查"明明改了配置怎么还是慢/还是报错"时的第一动作,很多人漏了它,导致把旧连接的结果当成新配置的问题来排查。
3. Windows 10 共享配置:从网络发现到 SMB 设置一次到位
3.1 网络发现服务为什么总是关闭
Windows 10 无论在"网络"里看不到别的电脑,先从网络发现查起。网络发现不是单一开关,它依赖四个服务协作:
| 服务名 | 显示名 | 作用 |
|---|---|---|
| fdPHost | Function Discovery Provider Host | 提供设备发现机制 |
| FDResPub | Function Discovery Resource Publication | 把自己的共享发布到网络 |
| SSDPSRV | SSDP Discovery | 发现基于 SSDP 的设备 |
| upnphost | UPnP Device Host | 托管 UPnP 设备 |
这四个服务只要有一个没启动,网络发现就时好时坏。我一般直接用命令行一次性搞定:
# 以管理员身份运行,设置四个服务自动启动并启动 Get-Service fdPHost, FDResPub, SSDPSRV, upnphost | Set-Service -StartupType Automatic Start-Service fdPHost, FDResPub, SSDPSRV, upnphost逻辑说明:Get-Service 拿到服务对象后,Set-Service -StartupType Automatic 把启动类型改成自动,避免重启后又变回手动。Start-Service 是立即拉起服务,不等重启。参数 -StartupType 支持 Automatic、Manual、Disabled 三种值,网络发现环境里必须 Automatic。
服务起来了之后,还要确认网络配置文件是"专用网络"。Windows 10 的公用网络会默认阻止网络发现和文件共享,切到专用网络才放行。在"设置 → 网络和 Internet → 状态 → 更改连接属性"里把网络配置文件改成"专用"。命令行也可以:
# 查看当前网络连接类型 Get-NetConnectionProfile # 将接口的 NetworkCategory 改为 Private(专用) Set-NetConnectionProfile -InterfaceIndex 12 -NetworkCategory PrivateGet-NetConnectionProfile 输出里的 InterfaceIndex 是你网卡的接口索引,改之前先看清楚是哪一块网卡,别把有线和无线一起误改了。NetworkCategory 参数有两个可选值:Private(专用)和 Public(公用),只有 Private 下文件共享才不会被系统防火墙直接拦掉。
3.2 共享文件夹的最小权限配置
配置共享时经常会看到两种入口:右键文件夹选"属性 → 共享",或选"高级共享"。前者配置的是简单共享,后者可以设置更细的权限。我的习惯是统一走 New-SmbShare 命令行,因为图形界面选项多,容易漏掉"Everyone 只读"和"特定用户可写"的组合设置。
# 创建共享:D:\share 共享名为 public,Everyone 可读,smbshare 用户可改 New-SmbShare -Name "public" -Path "D:\share" -FullAccess "smbshare" -ReadAccess "Everyone"逻辑说明:New-SmbShare 是本机创建一个 SMB 共享,Path 参数必须指向本地已存在的文件夹。ReadAccess 给 Everyone 是让所有能访问本机的用户都可以读取,FullAccess 只给 smbshare 账户是限定只有它能写入。权限范围不是累加关系,而是"共享权限 + NTFS 权限取交集"——Everyone 只读和 smbshare 完全控制交起来,smbshare 实际拿到的还是两者叠加后的写权限。
这里有个血泪经验:共享权限只是第一道门,NTFS 权限才是第二道门。D:\share 文件夹的"安全"选项卡里,如果 smbshare 账户没有"修改"权限,共享权限再大,实际写入时照样报"拒绝访问"。所以配置完共享,一定要回头检查 NTFS 权限。
3.3 防火墙放行哪些端口
SMB 服务的入站端口是 445,走的是 TCP。网络发现还需要 137/138(UDP)和 139(TCP,NetBIOS)。Windows 10 自带了"文件和打印机共享"防火墙规则组,不用一条条手动开端口,直接启用这个规则组即可:
# 启用内置的 SMB 入站规则 Enable-NetFirewallRule -Name "FPS-SMB-In-TCP"逻辑说明:Enable-NetFirewallRule 的作用是启用指定名称的防火墙规则,FPS-SMB-In-TCP 是 Windows 内置的"文件和打印机共享 (SMB-In)"入站规则,负责放行 TCP 445 端口。启用后如果还是访问不了,再单独放行 NetBIOS 相关规则:
# 查看当前 SMB 相关规则的状态,确认哪些是 Enabled Get-NetFirewallRule -DisplayGroup "文件和打印机共享" | Where-Object { $_.Enabled -eq 'True' }get 这条命令能看到规则名和状态,用 Where-Object 过滤 Enabled 为 True 的规则,对照一下有没有 SMB-In 相关的。如果之前用第三方安全软件优化过系统,规则组可能被整体禁用,这时候把整个 DisplayGroup 重新启用一遍更省事。
4. 访问凭据与 guest 账户:正确模型替代 guest 玄学
4.1 guest 账户为什么不靠谱
不少教程告诉你"共享文件夹访问失败先启用 guest",这实际上是把问题引向更深的坑。Windows 10 的 guest 账户有两个天然限制:
- guest 账户默认禁用,手动启用后,系统策略"账户:使用空密码的本地账户只允许进行控制台登录"默认开启,远程通过网络访问时,空密码的 guest 会被直接拒绝。
- 即使你把 guest 解禁并给了共享权限,Windows 10 从 1709 版本开始,默认拒绝不安全的来宾登录,连接时依然提示凭据不满足。
换句话说,guest 在网络共享场景下是个死胡同。你花半小时去改本地安全策略、改注册表 AllowInsecureGuestAuth,不如创建一个普通的本地账户来得干净。这个"不再折腾 guest"的判断,是我在网络维护里最想传递的第一个观点。
guest 唯一还能用的场景,是纯内网、无敏感数据、且所有客户端都是旧系统的环境。只要内网里有超过一台 Windows 10 或 NAS,我都不建议碰 guest。
4.2 正确做法:专用共享账户与凭据管理
正确的凭据模型是:目标机器上创建一个本地账户,只给它共享目录的访问权限,然后客户端用这个账户连接。创建账户的命令:
# 在共享主机上创建本地账户 smbshare net user smbshare YourPass!123 /add逻辑说明:net user 是经典的本地用户管理命令,格式是"用户名 密码 /add",斜杠参数表示新增。Windows 10 对密码策略有最低要求:至少 8 位且包含字母、数字、符号三类,YourPass!123 只是示例,实际设置时别用这个弱密码。
账户建好后,把它加到共享权限里:
# 给 smbshare 账户授予 public 共享的读写权限 Grant-SmbShareAccess -Name "public" -AccountName "smbshare" -AccessRight Change逻辑说明:Grant-SmbShareAccess 修改的是共享层面的 ACL,AccessRight 有 Change、Read、Full 三个取值,"Change"对应读写和删除,"Full"则能修改共享权限本身,一般给 Change 就够。NTFS 层别忘了同步给 smbshare 设置"修改"权限。
客户端连的时候,经典做法是用 net use 指定凭据:
:: 在访问端执行,先清理旧凭据再连接 cmdkey /delete:192.168.1.10 net use \\192.168.1.10\public /user:smbshare YourPass!123cmdkey /delete 是清掉目标机可能残留的旧凭据,防止系统优先使用缓存导致新密码进不去。net use 后面的 /user:参数指定用户名,密码直接跟在后面,如果不想在命令行明文写密码,就把密码换成星号:
net use \\192.168.1.10\public /user:smbshare *星号的作用是让系统弹出凭据输入框,运行时手动敲密码,输错还能重来。这个方式在服务器核心版或远程管理场景下一样适用,推荐优先用。
4.3 记住凭据之后怎么清理
连接时如果勾了"记住凭据",Windows 会把账户密码存进凭据管理器。好处是下次免输,坏处是共享主机改了密码,客户端这边依旧拿旧凭据去连,怎么输新密码都没用。
处理方式从命令行走最快:
:: 列出当前存储的所有 Windows 凭据 cmdkey /list :: 删除指定目标的凭据 cmdkey /delete:192.168.1.10cmdkey /list 会输出来源(目标地址)、类型和用户名,先在列表里找到目标 IP,再用 /delete 精确删除。注意 /delete 后面的地址格式要跟存储时完全一致,192.168.1.10 和 192.168.1.10(用户名)在 cmdkey 里是两个不同条目,删错不要紧,删干净的代价只是会重新弹一次凭据框。
图形界面的清理路径在"控制面板 → 用户账户 → 凭据管理器 → Windows 凭据",找到对应条目手动移除。这两条路效果一样,推荐用 cmdkey,因为快且不受凭据管理器界面缓存的影响。
5. SMB 排查清单:五个高频故障的根因与处理
5.1 找不到网络路径 0x80070035
现象:访问 \192.168.1.20\share,资源管理器直接弹"找不到网络路径 (0x80070035)"。
原因:这个报错底下通常藏着三种情况:目标机的 Server 服务没启动、445 端口没在监听、防火墙拦截了入站 SMB 流量。很多人去检查 SMB 版本,把协议翻了个遍,其实问题根本不在协商,而在端口根本不通。
解决:先确认 445 是否在监听:
netstat -ano | findstr :445有输出且状态是 LISTENING,说明服务在跑,问题大概率在防火墙。没有输出,说明 Server 服务挂了:
# 启动 Server 和 Workstation 服务并设为自动 Set-Service LanmanServer -StartupType Automatic Set-Service LanmanWorkstation -StartupType Automatic Start-Service LanmanServer Start-Service LanmanWorkstation然后重新访问。如果监听正常还是报错,去防火墙检查"文件和打印机共享"规则组是否被禁用,照着 3.3 节 Enable-NetFirewallRule 处理。
5.2 凭据输入正确但提示"用户名或密码不正确"
现象:弹窗让输用户名密码,输入的明明是共享主机上的本地管理员密码,依然报错。
原因:绝大多数时候不是密码错,而是目标机上根本不存在你输的那个用户名,或者该用户名在共享权限里没被分配。曾经踩过的最典型的坑:共享主机用的是微软账户登录,本地账户列表里没有对应的用户名,客户端输入微软账户邮箱和密码,系统拿邮箱当用户名去查本地账户,当然查不到。
解决:在共享主机上确认本地账户:
net user列出所有本地账户,找一个你打算用来访问的,没有就按 4.2 节建一个。然后确认这个账户在共享权限里:
Get-SmbShareAccess -Name "public"输出的 AccessControl 列表里要有你要用的账户,没有就用 Grant-SmbShareAccess 补上。这一步做完再去客户端重连,基本都能过。
5.3 能列共享名但进不去目录
现象:\192.168.1.20 能进,共享名也看得见,双击进目录却提示"没有权限使用此资源"。
原因:共享权限给了读了,但 NTFS 权限没给。NTFS 和共享权限是两层独立的访问控制,最终权限取两者的交集。共享层只控制能不能连上这个共享,NTFS 层控制连上之后能不能读、能不能写。
解决:右键共享目录 → 属性 → 安全 → 编辑 → 添加用户并勾选"修改"。"修改"权限包含读写、执行和删除,对大多数共享场景足够。命令行方式也可以:
icacls "D:\share" /grant "smbshare:(OI)(CI)M"icacls 是 Windows 的 ACL 修改命令,(OI)(CI) 表示对象继承和容器继承,让子目录和文件也继承这条权限,M 代表修改。执行完再连一次,权限就通了。
5.4 拷贝速度慢或长时间空闲后卡死
现象:局域网千兆环境,拷贝大文件只有 20-30MB/s,或者共享文件放着不动超过半小时再访问就转圈。
原因:速度慢大概率是协商落到了 SMB1,性能上限就摆在那里;空闲后卡死,大多是网卡节能导致的连接假死,系统在空闲时把网卡降速或断电来省电,SMB 连接发现对端无响应后挂起。
解决:先看协商版本:
Get-SmbConnection | Select-Object ServerName, DialectDialect 是 1.0 的,去共享主机执行 Set-SmbServerConfiguration -EnableSMB1Protocol $false,强制双方走 SMB3。Dialect 是 3.x 还慢,检查网卡属性"电源管理",取消"允许计算机关闭此设备以节约电源"。
5.5 Windows 更新后突然全部连不上
现象:上周还能访问的共享,这周一开机全部打不开,有的报"不能访问此共享文件夹,因为组织的安全策略"。
原因:Windows 10 安全更新会收紧 SMB 策略,常见的两个方向:一是重新禁用 SMB1,二是开启"不安全的来宾登录"拒绝策略。如果你之前为了接老设备开过 SMB1 或改过 AllowInsecureGuestAuth,一次大更新可能把这些改动全部还原。
解决:确认 SMB1 状态和签名策略:
Get-SmbServerConfiguration | Select-Object EnableSMB1Protocol, EncryptData Get-SmbClientConfiguration | Select-Object RequireSecuritySignatureEnableSMB1Protocol 是 $false 但确有必要用老设备,按 2.2 节的方式重新开启;RequireSecuritySignature 是 $true 且对方不支持 SMB3 签名,会话协商会直接失败,这种机器一般只有两个出路:换支持 SMB3 的设备,或在客户端临时关闭签名要求。关闭签名会降低安全性,只建议在隔离网段这么做,别用到有敏感数据的共享上。
6. 验证与进阶:两条命令确认协议版本,再把签名打开
配置做完,验证这一步最容易偷懒。很多人共享能开了就不管了,但"能开"和"跑在正确的协议上"是两回事。我习惯的收尾动作只有两条命令,一条看协商,一条看服务端策略:
# 确认实际协商出的协议版本 Get-SmbConnection | Select-Object ServerName, Dialect # 确认服务端加密和 SMB2/3 状态 Get-SmbServerConfiguration | Select-Object EnableSMB1Protocol, EnableSMB2Protocol, EncryptDataDialect 不是 3.0.2 就是 3.1.1,说明网络路径和防火墙都正常,协议协商没被老设备拉低。EnableSMB1Protocol 是 $false,说明没有把整个内网暴露在老协议下。EncryptData 是 $true 时,SMB3 会话会自动加密,这对跨交换机或经过不可信网段传文件来说是最后一道保险。
进阶场景里,如果要求更强的数据完整性,打开 SMB 签名:
# 服务端要求签名 Set-SmbServerConfiguration -RequireSecuritySignature $true # 客户端也要求签名 Set-SmbClientConfiguration -RequireSecuritySignature $true设置立即生效,但有个前提:所有客户端都要支持 SMB3 签名,混着老系统时开了会一片哀嚎。我的建议是先在隔离测试网段开,确认所有对接设备都不报错再推全量。
这套配置流程跑下来快的话十分钟,但真正值钱的不是那几条命令,而是排查时的顺序——先端口、再服务、再协议、再权限,别一上来就改版本。从那以后,我每次配置完共享都会强制走一遍 Get-SmbConnection,确认 Dialect 是 3.0.2 或 3.1.1 才收工。希望帮到你。
本文还有配套的精品资源,点击获取