手上有一台没接显示器的机器,或者一台塞在机房角落的 Linux 服务器,图形界面明明装了却看不见,这种别扭劲儿估计每个搞运维和嵌入式开发的人都体会过。想跑个带界面的开发工具、想让不熟悉命令行的同事也能上去点两下、想调一下虚拟机的桌面环境,最省事的路子就是装一套 VNC 服务端,然后用 VNC Viewer 从自己电脑上连过去。VNC Viewer 这个客户端工具很轻,跨平台做得也好,Windows、macOS、Linux 上都有对应版本,连 Linux 的图形桌面是一个很成熟也很实用的组合。
这篇文章不打算只丢几条命令了事。我会从"为什么选 VNC"讲起,把服务端该装在哪一端、虚拟桌面和共享物理屏有什么区别、端口和显示号怎么换算、黑屏灰屏怎么排查这些容易卡住人的点一次说清楚。整套流程我自己在 Ubuntu、Debian、CentOS 以及几个国产 Linux 发行版上都跑过,踩过的坑会一并写进来。不管你是刚装完虚拟机的新手,还是手上有几台服务器要做图形化运维的老手,照着走一遍应该能省下不少试错的时间。
1. 需求拆解与方案选型:VNC 该装在哪一端
1.1 先分清服务端和客户端,别把方向装反
新手最容易犯的第一个错,是把 VNC 装错了机器。这里必须先建立一个基本认知:VNC 是一套客户端-服务端架构的远程桌面协议。你要看的那个 Linux 桌面,它的机器上必须运行 VNC 服务端(server),负责把屏幕画面编码后通过网络发出去;而你自己手边这台电脑上装的是 VNC 客户端(viewer),负责接收画面并把你的键鼠操作回传。方向是从客户端主动连服务端,反过来是不通的。
所以标题里说的"设置 VNC Viewer 连接 Linux",实际包含两件事:Linux 端要装并配好服务端,本地端要装好 Viewer 并配置连接参数。很多人只装了 Viewer 就开始找为什么连不上,问题往往出在服务端根本没跑起来。我一般建议把这两端当成两个独立的小任务来做,先把 Linux 端的服务跑通、用vncviewer或者netstat自检一遍,再去配客户端,排查范围会小很多。
还有一点要提前说清楚:VNC 服务端通常不是"一个人装好所有人共用",它跟用户账号是绑定的。同一个用户可以用不同显示号开多个桌面,不同用户各自开各自的。这就意味着后面涉及密码、配置文件、日志的路径,基本都在各自的家目录下,/etc里主要是全局默认值。理解了这个结构,后面看配置文件就不会迷路。
1.2 几种远程图形方案横向对比,选对工具少折腾
远程访问 Linux 图形界面不止 VNC 一条路,选错了会一直在填坑。下面这张表是我这几年实际用下来的对比,参数不一定绝对,但方向上的判断是靠谱的。
| 方案 | 原理 | 典型延迟 | 是否需要本地装客户端 | 适合场景 |
|---|---|---|---|---|
| VNC | 服务端截屏编码传输 | 中等 | 是 | 跨平台远程桌面、无人值守、教学演示 |
| RDP(xrdp) | Windows 远程桌面协议 | 较低 | Windows 自带 | 以 Windows 客户端为主、办公场景 |
| X11 转发 | 通过 SSH 转发单个窗口 | 局域网尚可,广域网差 | 需要本地 X Server | 只开一两个 GUI 工具 |
| 网页化方案 | 浏览器直接渲染 | 视实现而定 | 不需要 | 临时演示、不方便装客户端的环境 |
选 VNC 的核心原因是三个字:通用性。它在 Windows、macOS、Linux、甚至手机上都能找到客户端,协议本身也足够简单,出问题好排查。RDP 在纯 Windows 客户端环境下体验更好,但 Linux 侧的 xrdp 版本和桌面环境的兼容性有时候会让人头疼。X11 转发适合"我只想跑一个 gedit"这种轻量需求,广域网上跑整个桌面会卡到怀疑人生。
提示:如果你的目标机器在公网或不受信任的内网环境中,不要直接把 VNC 端口暴露出去。VNC 早期版本的认证强度不高,后面第 4 章我会讲怎么用 SSH 隧道把流量包起来。
1.3 三种典型部署形态,先想清楚你要哪一种
同样是装 VNC,背后需求其实分三类,选错了形态会导致"连上了但不是我想要的画面"。
第一种是独立虚拟桌面。服务端自己启一个新的 X 会话和桌面环境,跟你机器物理显示器上显示的内容完全无关。这是 TigerVNC 这类服务端的默认行为,也是服务器上最常用的形态——机房那台机器本来就没接显示器,开个虚拟桌面正合适。缺点是你在这上面开的程序,跑到物理屏幕前是看不到的。
第二种是共享物理显示器。镜像的是已经登录的物理桌面,你看到的和坐在机器前面的人看到的是同一个画面,鼠标会打架。这种要靠x11vnc来实现,典型场景是远程协助、给客户演示、或者树莓派这种接了屏幕又想远程操作的设备。
第三种是在容器或 WSL 里跑。这种环境下没有真实的 X Server,需要额外配虚拟显示,坑也最多,通常建议直接用独立虚拟桌面模式,别去碰共享物理屏。
搞清楚这三种的区别,后面选择装 TigerVNC 还是 x11vnc 就不会犹豫了。我的习惯是:服务器和开发机用 TigerVNC 开虚拟桌面,需要远程帮人看现场用 x11vnc,两个不吃亏。
2. Linux 服务端部署:TigerVNC 从装包到开机自启
2.1 环境摸底与软件源准备
动手之前先花两分钟摸底,能避免后面一半的报错。要确认的东西不多:发行版和版本、桌面环境类型、有没有装过其他 VNC 服务端、防火墙状态、以及你的账号有没有 sudo 权限。
cat /etc/os-release echo $XDG_CURRENT_DESKTOP dpkg -l | grep -i vnc # Debian 系 rpm -qa | grep -i vnc # RedHat 系 sudo ufw status # 或者 firewall-cmd --state这里有一个特别容易忽略的点:发行版决定了你装哪个包、用哪套配置路径。Debian 和 Ubuntu 上是tigervnc-standalone-server,RedHat 系上是tigervnc-server,而一些国产 Linux 发行版虽然基于 Debian 或 RedHat,但默认仓库里的包名和版本号可能有差异,最好先用apt search vnc或yum search vnc看一眼实际可用的包。
另外要注意的是SELinux。在开启 enforcing 模式的 RedHat 系系统上,VNC 服务经常因为策略限制起不来,日志里能看到 permission denied 之类的内容。这时候先用getenforce确认状态,临时setenforce 0验证一下是不是它的问题,确认是了就针对性地放策略,而不是长期关掉 SELinux,后者是运维里的大忌。
软件源方面还有一条实操经验:国内环境下,如果你的镜像源指向的地址响应慢,安装几十兆的包会等很久。可以先确认源是否顺畅,有必要的话换一个响应快的镜像源。这一步跟 VNC 本身无关,但实实在在影响你的第一次体验。
2.2 安装 TigerVNC 与设置访问密码
包名确认之后安装就很简单了。以 Debian/Ubuntu 为例:
sudo apt update sudo apt install -y tigervnc-standalone-server tigervnc-common装完之后不要急着启动服务,先设密码。这一步的顺序很重要,因为首次vncserver启动时会去读~/.vnc/passwd,如果这个文件不存在,某些版本会直接失败。
vncpasswd执行后会让你输入并确认一个密码,然后问你要不要设置"view-only password"。这个只读密码挺有用:给学生演示或者给同事看界面的时候,可以只给只读密码,对方能看不能动,避免误操作。密码文件默认落在~/.vnc/passwd,权限会被自动设成 600,这个别去手动改宽。
注意:VNC 的密码机制历史上有过一个限制——只取前 8 位有效字符。虽然新版本已经改善,但在做兼容性配置时,把密码控制在 8 位以内、包含大小写和数字,是覆盖面最广的做法。另外,真正的安全加固要靠通道加密,密码强度只是其中一环。
设完密码,先手动启动一次,看看能不能跑起来:
vncserver :1 -geometry 1920x1080 -depth 24如果输出里没有明显的报错,说明服务端起来了,显示号是 1。这个显示号后面会反复用到,先记住它。
2.3 配置文件与 xstartup 的正确写法
服务能起来不代表画面正常。十个人里有八个卡在 xstartup,这是 VNC 配置里最关键的一个文件。它的作用是告诉 VNC 服务端:新会话启动之后,要拉起哪个桌面环境、带哪些环境变量。
不同服务端读的文件位置不完全一样。TigerVNC 的常见路径是~/.vnc/xstartup,新版本还会读~/.vnc/config。先看配置文件:
mkdir -p ~/.vnc cat > ~/.vnc/config <<'EOF' geometry=1920x1080 depth=24 dpi=96 session=xfce alwaysshared EOFalwaysshared表示允许多个客户端同时连同一个会话,做演示或者结对调试的时候很有用。dpi=96是为了解决高分屏上字体过小的问题,不加的话有些设备上字小得看不清。
然后是 xstartup,我用得最稳的是 XFCE 版本:
cat > ~/.vnc/xstartup <<'EOF' #!/bin/sh unset SESSION_MANAGER unset DBUS_SESSION_BUS_ADDRESS [ -x /etc/X11/xinit/xinitrc ] && . /etc/X11/xinit/xinitrc exec startxfce4 EOF chmod +x ~/.vnc/xstartup为什么推荐 XFCE 而不是 GNOME 或 KDE?因为 GNOME 从 3.x 开始强依赖硬件加速和 DBus 会话管理,在 VNC 这种虚拟 X 环境里很容易出现灰屏、只有背景没面板、图标加载不出来等问题。KDE 相对好一些但资源占用大。XFCE 轻量、依赖少、对虚拟显示友好,远程桌面场景下的综合体验是最好的。这不是说 GNOME 一定不行,而是同样的时间成本,XFCE 能让你更快用上。
unset SESSION_MANAGER和unset DBUS_SESSION_BUS_ADDRESS这两行看着莫名其妙,但作用很实在:它们清掉从系统继承过来的会话变量,避免 VNC 会话去连接物理桌面的会话总线,从而防止启动卡死或画面异常。这个细节很多教程不会写,但它是灰屏问题最常见的解法之一。
提示:如果确实要用 GNOME,通常要改成
exec dbus-launch --exit-with-session gnome-session这类写法,而且需要额外装dbus-x11。即便如此,个别版本仍会有兼容问题,做好心理准备。
2.4 systemd 常驻、开机自启与防火墙放行
手动跑的进程关掉终端就没了,实际用起来肯定要托管成服务。TigerVNC 有两种做法:用官方的vncserver@.service模板(RedHat 系比较多),或者自己写一个用户级 unit。我更推荐用户级 unit,因为它天然支持多用户、不需要 root、清理也干净。
# ~/.config/systemd/user/vncserver.service [Unit] Description=TigerVNC Server (display :1) After=network.target [Service] Type=forking ExecStartPre=-/usr/bin/vncserver -kill :1 ExecStart=/usr/bin/vncserver :1 ExecStop=/usr/bin/vncserver -kill :1 Restart=on-failure [Install] WantedBy=default.target启用并启动:
systemctl --user daemon-reload systemctl --user enable --now vncserver.service systemctl --user status vncserver.service这里有个坑要单独拎出来说:用户级 systemd 服务默认在用户完全登出后会被回收,表现为你 SSH 断开一段时间后 VNC 就没了。解决办法是开启 linger:
sudo loginctl enable-linger $USER这一条我强烈建议加上,它是"VNC 用着用着就断了"最常见的根因。
接着是防火墙。VNC 的端口规则很固定:显示号加 5900 就是 TCP 端口。显示号 :1 对应 5901,:2 对应 5902,:0 对应 5900。
sudo ufw allow 5901/tcp # Ubuntu/Debian sudo firewall-cmd --permanent --add-port=5901/tcp && sudo firewall-cmd --reload # RedHat 系如果前面开了 SELinux,还要放行对应端口:
sudo semanage port -a -t vnc_port_t -p tcp 5901做完这几步,服务端算是齐活了。我会习惯性地用ss -lntp | grep 5901确认监听状态,看到LISTEN才算真的成功,光看服务状态是 running 有时候会有假象。
3. 共享物理显示器:x11vnc 的适用场景与配置
3.1 什么时候必须用 x11vnc 而不是 TigerVNC
TigerVNC 开的是虚拟桌面,它跟物理屏幕是两条线。这在服务器上完全没问题,但有些场景下就是不行。比如你在给客户远程演示一台接了投影的机器,客户要看的就是投影上那个画面;再比如树莓派接了个小屏幕做信息展示,你想远程上去调,但调的内容必须同步显示在物理屏上;还有一种是老旧的工控设备,系统里只有一个已经登录的桌面会话,你没法再开新的。
这些情况共同的要求是:必须镜像那个已经存在的、正在显示的画面。能满足这个需求的工具就是 x11vnc,它的工作方式是直接抓取某个已存在的 X display(通常是:0),把内容转发出去。它跟你坐在机器前操作的是同一个会话,鼠标指针会共享,所以你在远程动鼠标,物理屏上的指针也会动,这一点要提前跟现场的人说好。
反过来说,如果你的机器根本没接显示器、也不需要谁来看着画面,那就没必要用 x11vnc。它比 TigerVNC 更依赖已有的 X 会话,一旦那个会话挂了(比如切到登录界面、或者用户登出),VNC 也就断了,稳定性上不如虚拟桌面模式。
3.2 安装、密码持久化与 systemd 托管
x11vnc 的安装很简单:
sudo apt install -y x11vnc密码要单独存一份文件,因为它的认证不走~/.vnc/passwd那套:
x11vnc -storepasswd ~/.vnc/x11vnc.pass这个命令执行后会提示你输入密码,并在指定路径生成认证文件。然后在启动时用-rfbauth指过去。手动验证一次:
x11vnc -display :0 -auth guess -forever -loop -noxdamage -repeat \ -rfbauth ~/.vnc/x11vnc.pass -rfbport 5900 -shared -o ~/.vnc/x11vnc.log参数逐个解释一下,这些是我调过很多次之后留下的组合:-display :0指定要抓的 X 显示;-auth guess让程序自己去猜 X 授权文件的位置,省掉手动指定的麻烦;-forever保证客户端断开后服务还在;-loop在连接意外中断时自动重建监听;-noxdamage关掉 X Damage 扩展,能规避某些显卡驱动下画面局部不刷新的问题;-repeat允许按键自动重复;-shared允许多人同时看。
托管成 systemd 服务,写一个系统级 unit:
# /etc/systemd/system/x11vnc.service [Unit] Description=x11vnc service After=display-manager.service Requires=display-manager.service [Service] Type=simple ExecStart=/usr/bin/x11vnc -display :0 -auth guess -forever -loop -noxdamage \ -repeat -rfbauth /root/.vnc/x11vnc.pass -rfbport 5900 -shared Restart=on-failure [Install] WantedBy=multi-user.targetsudo systemctl daemon-reload sudo systemctl enable --now x11vnc注意:x11vnc 跑在 root 下时,密码文件的路径要跟启动用户实际能读到的路径一致,上面写的是
/root/.vnc/x11vnc.pass。如果你把密码存在自己家目录下却用 root 启动,会直接认证失败,日志里提示读取不到认证文件。
还有一点经验:x11vnc 对 Wayland 支持不好。现在不少发行版默认已经切到 Wayland 会话,这种情况下-display :0抓不到东西,表现就是连接上了但黑屏。解决方式是在登录界面切换回 X11 会话,或者直接改用 TigerVNC 的虚拟桌面。这个坑很隐蔽,因为从日志上看不出明显错误。
4. VNC Viewer 客户端连接全流程
4.1 客户端下载渠道与版本选择
服务端跑起来之后,轮到本地的 Viewer 了。这一步看着简单,但下载渠道这块值得说两句。VNC 客户端主要有几家:RealVNC 的 Viewer、TigerVNC 自带的vncviewer、以及 Linux 上的 Remmina。选择上我的建议是这样的:
- Windows / macOS:用 RealVNC Viewer,安装包干净,界面友好,免费版用于个人连接足够。
- Linux 桌面:直接用 TigerVNC 的
vncviewer,命令行走起,方便脚本化。 - 需要管理多台设备:Remmina,支持保存多套连接配置,切换方便。
下载渠道上,优先去软件官方网站。这一点必须强调,网上有不少打着"绿色版""汉化版"旗号的安装包,捆绑推广软件是常事,严重的还可能带上其他东西。下载完成后,如果页面提供了校验值,花一分钟核对一下哈希是值得的:
# 以 sha256 为例 sha256sum VNC-Viewer-xxxx.exe版本选择上不用追求最新。Viewer 的协议向后兼容做得不错,稍微旧一点的稳定版反而更省心。唯一要注意的是某些企业内网会限制安装包的来源,这时候让 IT 统一分发是更稳妥的做法。另外 macOS 上首次运行会提示"来自身份不明的开发者",在系统设置的隐私与安全性里放行一次即可。
4.2 地址端口写法与显示号换算,这里最容易搞错
连接的时候,地址栏里填什么,是新手最容易栽的地方。规则其实就一条:VNC 端口 = 5900 + 显示号。但客户端的输入格式有两套,用混了就连不上。
| 输入格式 | 含义 | 示例 | 对应端口 |
|---|---|---|---|
| IP:显示号 | 单冒号,数字是显示号 | 192.168.1.20:1 | 5901 |
| IP::端口 | 双冒号,数字是真实端口 | 192.168.1.20::5901 | 5901 |
| IP | 不写,默认显示号 0 | 192.168.1.20 | 5900 |
最容易犯的错是把192.168.1.20:5901填进去,客户端会把它解释成"显示号 5901",于是去连 5900+5901=11801 端口,当然连不上。要么写:1,要么写::5901,就这两条路。
TigerVNC 自带的命令行客户端更简单,直接用显示号:
vncviewer 192.168.1.20:1如果服务端换了非标准端口,也可以显式指定:
vncviewer 192.168.1.20::15901提示:如果你不确定服务端到底监听在哪个端口,回到 Linux 上用
ss -lntp | grep -E '590[0-9]'看一眼,一切疑惑都会消失。别猜。
4.3 画质、编码与性能调优,局域网和广域网要分开调
VNC 的体验好坏,很大程度取决于编码和画质参数。默认设置下在局域网里通常够用,但如果跨网段、走无线、或者带宽受限,画面会卡得像幻灯片。这时候调参数是必要的。
先说服务端侧的编码。TigerVNC 支持Tight、ZRLE、Hextile、Raw等编码方式。Tight的压缩率高、CPU 开销适中,是默认选择也是通用性最好的。Raw完全不压缩,局域网千兆环境下延迟最低但带宽吃满,只在极低延迟需求下用。要改的话在~/.vnc/config里加一行:
# 让客户端协商决定,通常保持默认即可再说客户端侧。RealVNC Viewer 里有两个关键选项:Picture Quality和Scaling。家里或者办公室局域网,直接选High或Best,色彩保留 24 位;如果是跨运营商或者移动网络,降到Medium甚至Low,把色彩深度降到 16 位,流畅度会有肉眼可见的提升。
| 网络环境 | Picture Quality | 色彩深度 | 预期体验 |
|---|---|---|---|
| 千兆局域网 | Best | 24 位 | 接近本地 |
| 百兆内网 / Wi-Fi | High | 24 位 | 流畅,偶尔轻微延迟 |
| 跨网段 | Medium | 16 位 | 可用,滚动页面略有拖影 |
| 移动网络 | Low | 8~16 位 | 能操作,别指望看视频 |
分辨率也是一个取舍点。VNC 的画面是"画面变了才传",所以分辨率越大,需要传输的像素越多。我在 1080p 下用得很舒服,4K 在一般带宽下会明显感到滞后。如果只是为了跑命令行工具或者编辑器,把服务端 geometry 设成 1440x900 反而更省资源。
4.4 安全加固:密码、SSH 隧道与访问控制
前面提过,VNC 协议本身的认证强度不能算高,密码在传输过程中的保护也有限。所以只要环境不是完全可信的内网,都应该用 SSH 隧道把 VNC 流量包起来。这是我强烈建议的一个习惯,做法也不复杂。
在本地机器上执行:
ssh -N -L 5901:127.0.0.1:5901 user@192.168.1.20这条命令的意思是:把本地的 5901 端口,通过 SSH 通道转发到远端主机的 127.0.0.1:5901。执行后保持这个终端不动,然后在 VNC Viewer 里连接:
127.0.0.1:1这样做的效果是,VNC 的明文流量只存在于远端主机的本地回环和你的本机回环之间,中间网络里跑的都是 SSH 加密流量。配合这一步,服务端就可以只在127.0.0.1上监听,彻底不暴露到网络上。在~/.vnc/config里加上:
localhost或者在启动参数里用-localhost。加上之后,只有本机内部的连接能访问,外网扫描都扫不到端口,安全性提升是数量级的。
再配合几条基础措施:密码别用纯数字,控制好长度;不需要的时候停掉服务;定期看一眼~/.vnc/*.log里有没有异常的连接尝试记录。这些都是低成本但很有效的手段。
5. 常见问题排查实录
5.1 连不上:网络、端口、防火墙三层速查
连不上是最常见的问题,但原因基本集中在三个层次,按顺序查效率最高。我整理了一张速查表:
| 现象 | 可能原因 | 排查命令 | 处理方式 |
|---|---|---|---|
| 提示连接超时 | 网络不通或端口没监听 | ping、ss -lntp | grep 5901 | 检查服务是否启动、IP 是否正确 |
| 提示拒绝连接 | 服务没跑或防火墙拦截 | systemctl --user status vncserver | 启动服务、放行端口 |
| 连上后被立即断开 | 认证失败或配置错误 | tail -f ~/.vnc/*.log | 重新设密码、检查 xstartup |
| 只能从本机连,外部连不上 | 配置了 localhost 限制 | grep localhost ~/.vnc/config | 去掉该配置或用 SSH 隧道 |
排查时有个技巧:先在 Linux 本机上用vncviewer 127.0.0.1:1自己连自己。如果能连上,说明服务端没问题,故障在网络或防火墙;如果连不上,问题就在服务端,跟网络无关。这一步能把排查范围直接砍一半,我几乎每次都是从这开始的。
另外提醒一句,虚拟机里的 Linux 要注意网络模式。NAT 模式下宿主机无法直接访问虚拟机的端口,需要改成桥接模式或者做端口转发。这个坑在"虚拟机安装 Linux"的人群里非常高频。
5.2 黑屏、灰屏、只有鼠标:三个最典型的现象
服务连上了,但画面不对,这类问题的排查要按现象分类。
纯黑屏,什么都没有。大概率是 xstartup 没执行权限,或者里面指定的桌面环境根本没装。先确认权限:ls -l ~/.vnc/xstartup,看到-rwx才对。再看桌面环境是否存在:which startxfce4。如果返回空,说明 XFCE 没装,sudo apt install xfce4 xfce4-goodies补上。还有一种可能是 Wayland 会话下抓不到画面,处理方法前面说过。
灰屏加一个 X 型光标。这是 X 服务起来了,但桌面环境没拉起来。典型原因有两个:一是 xstartup 里exec后面的程序名写错了;二是缺 DBus,导致桌面环境的会话管理组件启动失败。回到 2.3 节那个模板,把两行unset加上,多数情况能解决。如果还不行,在 xstartup 里加一行把输出重定向到日志,看具体报什么错:
exec startxfce4 > ~/.vnc/xstartup.log 2>&1只有鼠标能动,或者画面是花的。画面花屏通常跟-noxdamage那个参数有关,说明服务端的画面刷新机制和显卡驱动配合有问题,反过来把-noxdamage加上或去掉试试。鼠标能动但画面不刷新,可能是压缩编码的问题,在客户端把画质调低、换一种编码试试。
5.3 中文输入、剪贴板、分辨率与鼠标偏移
画面正常之后,接下来会遇到一堆体验层面的小问题,这些在正经文档里往往一笔带过,但实际很影响使用。
中文输入法用不了。VNC 会话里的输入法依赖 DBus 和相关的环境变量,容器化或者精简系统上经常是空的。解决方式是确认 fcitx 或 ibus 装了,并且在 xstartup 里正确导出环境变量:
export GTK_IM_MODULE=fcitx export QT_IM_MODULE=fcitx export XMODIFIERS=@im=fcitx如果系统里装的是 ibus,把对应值换掉即可。要确认输入法真的启动了,可以在 VNC 桌面里打开终端执行fcitx5-diagnose看诊断结果,这个工具把常见配置问题列得很清楚。
剪贴板不通。VNC 的剪贴板需要一个小工具做桥梁,在桌面里跑起来就行:
vncconfig -nowin &把它放到 xstartup 里开机自动执行一次,之后本地和远端之间就能正常复制粘贴了。这个不起眼的小东西解决了我很多次"复制的命令粘不过去"的困扰。
分辨率不对、鼠标有偏移。分辨率可以在客户端连接时设置,也可以在服务端~/.vnc/config里改geometry。鼠标偏移一般是缩放比例引起的,检查客户端是否开了自动缩放,关掉通常就正常了。也可以进桌面后用xrandr查看和设置可用分辨率:
xrandr xrandr -s 1920x1080文件传输。要注意 VNC 协议本身不负责传文件,别指望拖拽就能拷东西。需要传文件用scp、sftp或者共享目录的方式,效率高得多。
5.4 断连、卡顿与多用户冲突
用久之后会遇到另一类问题,跟稳定性和并发有关。
用一会儿就断。前面提过 linger 那个坑,这是最常见的原因。还有一种情况是网络不稳定导致 TCP 连接被断,如果服务端没加Restart=on-failure,进程可能就退出了。加上重启策略能缓解。TigerVNC 本身也会在客户端断开后保持会话,但如果启动了-neverexit之类的参数行为会不一样,配置时要留意。
画面卡顿。优先怀疑带宽和编码,参考 4.3 节调画质。还有一种隐蔽原因是客户端所在的机器本身负载高,或者无线信号质量差。我在家办公时遇到过一次,最后发现是路由器 2.4G 频段干扰严重,换到 5G 就顺了,跟 VNC 一点关系都没有。
多用户冲突。同一个用户重复启动同一个显示号的 VNC,会直接报"已存在"的错。这时候要么换一个显示号,要么先 kill 掉旧的:
vncserver -kill :1如果是不同用户,各自用各自的显示号就行,互不干扰。这里有个小技巧:把服务命名成vncserver@:1.service这样的模板,用显示号做参数,管理起来清晰很多。
6. 日常维护的几条实用经验
6.1 日志定位与自检脚本
出问题时最可靠的线索永远是日志。TigerVNC 的日志默认在~/.vnc/<主机名>:<显示号>.log,x11vnc 用-o参数指定的路径。养成先看日志的习惯,比到处猜要快得多:
ls -lt ~/.vnc/*.log tail -n 100 ~/.vnc/*.log我给自己写了一个小自检脚本,每次连不上先跑一遍,省去重复敲命令:
#!/bin/bash echo "== 服务状态 ==" systemctl --user is-active vncserver.service echo "== 监听端口 ==" ss -lntp | grep -E '590[0-9]' || echo "没有 VNC 端口在监听" echo "== 最近日志 ==" tail -n 20 ~/.vnc/*.log 2>/dev/null echo "== 防火墙 ==" sudo ufw status 2>/dev/null | grep 590 || echo "没找到放行规则"这个脚本没什么技术含量,但它在排查时把"服务、端口、日志、防火墙"四件事一次摆出来,能省掉大量来回切换的时间。你也可以把检查项换成自己的习惯路径。
6.2 环境迁移与备份
最后一件事,是关于可复现性。一台机器上配好之后,如果想在别的机器上再来一遍,别凭记忆重敲,把关键文件打包带走:
tar czf vnc-conf-backup.tar.gz -C ~ .vnc/config .vnc/xstartup这里的思路是只带配置,不带密码文件。密码文件跟机器和用户相关,重新vncpasswd生成一次更干净。换机器之后把配置解开、改一下geometry和session的值,再按 2.4 节重新做一遍 systemd 和防火墙,一套新环境十分钟就能搞定。
我自己在这些机器上折腾下来最大的感受是,VNC 配置的难点不在于命令本身有多复杂,而在于步骤之间有依赖顺序,跳步就报错。密码先设、xstartup 先测通、linger 先开启,这三件事按顺序做完,后面基本不会有大问题。至于画面调优和安全加固,那都是稳定之后锦上添花的事。如果哪一天你要把环境往新版本的系统上搬,前两节里那条日志自检的习惯会帮上大忙,因为发行版升级往往改的是包名和默认路径,报错信息却不会骗人。