在多屏、多电脑办公环境里,鼠标键盘联动工具可以解决"人如何同时操作两台电脑"的问题,但它并不能天然解决"一个应用里的业务动作如何同步到另一台电脑"的问题。
本文记录一套已经落地的双 Windows 电脑联动方案:股票点击联动走 HTTP,远程维护和部署走 SSH,文件传输走 SCP 或压缩包中转。这个方案的核心目标是:主力工作机点击股票行时,另一台电脑上的通达信也能自动切换到对应股票;同时,两台电脑之间可以通过命令行做部署、检查、同步文件和远程维护。
一、实际环境
当前两台电脑在同一局域网内:
|-----------|-------------------|------------------|
| 角色 | IP | 说明 |
| 本机 / 当前电脑 | `192.168.1.234` | 运行选股程序,也可以接收远端联动 |
| 远端电脑 | `192.168.1.29` | 打开通达信,也可以运行同一套代码 |
项目目录:
|----------|-------------------------|
| 机器 | 路径 |
| 本机项目 | `F:\波段投资\波段投资选股v23` |
| 远端项目 | `H:\波段投资回测` |
| 远端临时中转目录 | `C:\Temp\tdxdeploy` |
端口规划:
|----------------|-----------|----------|
| 用途 | 协议 | 端口 |
| 股票点击联动 | HTTP | `8765` |
| 远程登录、命令执行、文件传输 | SSH / SCP | `22` |
整体设计可以概括为一句话:
> 业务联动用轻量 HTTP,系统维护用 SSH。
二、为什么不用 Mouse without Borders 直接完成业务联动
Mouse without Borders 适合解决鼠标键盘跨电脑操作问题。比如鼠标从一台电脑移动到另一台电脑,键盘输入跟随当前焦点。
但股票点击联动不是"输入设备联动",而是"业务事件联动":
- 用户在选股程序中点击一只股票。
- 程序识别出股票代码,例如 `600519`。
- 程序把这个股票代码发送到另一台电脑。
- 另一台电脑收到代码后,通过本机通达信联动逻辑切换股票。
Mouse without Borders 不知道"你点击的是哪只股票",也不会自动把股票代码变成远端应用事件。所以这里需要在应用层增加一条消息通道。
三、总体架构
```mermaid
flowchart LR
A"本机选股程序\
点击股票行" --> B"tdx_link.py\
本机联动 + HTTP 发送"
B --> C"HTTP 请求\
http://192.168.1.29:8765/link?code=股票代码"
C --> D"远端 tdx_remote_server.py\
接收股票代码"
D --> E"远端通达信\
Windows 消息联动"
F"Codex / PowerShell" --> G"SSH 22 端口"
G --> H"远端命令执行\
部署 / 检查 / 启停服务"
F --> I"SCP 文件传输"
I --> J"C:\\\\Temp\\\\tdxdeploy\
远端中转目录"
这套架构分成两条链路:
第一条是业务链路:
```text
点击股票行 -> 提取股票代码 -> HTTP 发送 -> 远端接收 -> 调用远端通达信联动
第二条是维护链路:
```text
本机命令行 -> SSH 登录远端 -> 执行命令 / 传文件 / 部署服务
两条链路相互独立。即使远端 HTTP 服务没有启动,也不应该影响本机选股程序正常使用。
四、股票点击联动:HTTP 方案
股票联动使用 HTTP,而不是 SSH。
原因很简单:股票点击是高频、轻量、实时的业务动作。HTTP 请求成本低,结构简单,适合作为局域网内两台应用之间的事件通知。
1. 发送端职责
发送端只负责一件事:把股票代码发出去。
例如本机点击 `600519` 时,请求远端:
```powershell
Invoke-RestMethod "http://192.168.1.29:8765/link?code=600519"
远端点击股票时,也可以反向请求本机:
```powershell
Invoke-RestMethod "http://192.168.1.234:8765/link?code=600519"
这也是双边通信的关键:两台电脑都运行接收服务,同时配置对方为发送目标。
2. 接收端职责
接收端运行 `tdx_remote_server.py`,监听 `8765` 端口。
收到请求后,接收端做三件事:
- 解析 HTTP 请求里的股票代码。
- 校验股票代码格式。
- 调用本机已有的通达信联动逻辑,把股票代码广播给通达信。
也就是说,发送端不直接控制远端通达信窗口。发送端只发股票代码,真正的通达信联动发生在接收端本机。
这个边界非常重要。它让系统更稳:
```text
本机不需要知道远端通达信窗口句柄。
本机不需要控制远端桌面。
本机只需要知道远端 HTTP 地址。
3. 配置文件
联动配置放在 `tdx_remote_config.json`,和 `tdx_link.py`、`tdx_remote_server.py` 放在同一目录。
本机配置示例:
```json
{
"enabled": true,
"local_enabled": true,
"hosts": [
"192.168.1.29:8765"
],
"timeout": 0.4,
"verbose": false
}
远端配置示例:
```json
{
"enabled": true,
"local_enabled": true,
"hosts": [
"192.168.1.234:8765"
],
"timeout": 0.4,
"verbose": false
}
字段含义:
|-------------------|----------------------------|
| 字段 | 含义 |
| `enabled` | 是否启用远程 HTTP 联动 |
| `local_enabled` | 是否同时执行本机通达信联动 |
| `hosts` | 对方电脑的 HTTP 接收地址 |
| `timeout` | HTTP 请求超时时间,建议保持较短 |
| `verbose` | 是否显示远程联动错误,日常建议为 `false` |
4. 为什么发送失败不能影响本机
实际办公时,另一台电脑可能关机、休眠、没开服务,或者通达信没有打开。
因此发送端必须采用"尽力而为"的设计:
```text
远端在线:发送成功,远端通达信切换股票。
远端离线:发送失败,但本机程序继续正常运行。
所以配置里建议:
```json
{
"timeout": 0.4,
"verbose": false
}
短超时可以避免点击股票时卡顿;关闭 verbose 可以避免远端没开机时反复弹错误。
五、远程维护:SSH 方案
HTTP 负责业务联动,但不适合做部署、查日志、复制文件、启动服务。
这些事情应该交给 SSH:
```powershell
ssh Administrator@192.168.1.29
SSH 打通后,本机可以直接操作远端:
```powershell
ssh Administrator@192.168.1.29 "hostname"
ssh Administrator@192.168.1.29 "Get-ChildItem 'H:\波段投资回测'"
ssh Administrator@192.168.1.29 "Get-Service sshd"
如果本机存在加密私钥,SSH 可能优先询问私钥 passphrase,而不是 Windows 密码。此时可以显式使用密码登录:
```powershell
ssh -o PubkeyAuthentication=no Administrator@192.168.1.29
SCP 同理:
```powershell
scp -o PubkeyAuthentication=no .\tdx_remote_server.py Administrator@192.168.1.29:"C:/Temp/tdxdeploy/"
六、Windows 上启用 OpenSSH Server
远端电脑需要安装并启动 OpenSSH Server。
以管理员身份打开 PowerShell,执行:
```powershell
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.*'
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd
Set-Service -Name sshd -StartupType Automatic
放行防火墙:
```powershell
if (-not (Get-NetFirewallRule -Name sshd -ErrorAction SilentlyContinue)) {
New-NetFirewallRule `
-Name sshd `
-DisplayName "OpenSSH Server (sshd)" `
-Enabled True `
-Direction Inbound `
-Protocol TCP `
-Action Allow `
-LocalPort 22
}
建议设置默认 Shell 为 PowerShell:
```powershell
New-ItemProperty `
-Path "HKLM:\SOFTWARE\OpenSSH" `
-Name DefaultShell `
-Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" `
-PropertyType String `
-Force
检查 SSH 是否可用:
```powershell
Test-NetConnection -ComputerName 192.168.1.29 -Port 22
返回 `TcpTestSucceeded: True` 表示链路可用。
七、文件传输:SCP 与压缩包中转
两台 Windows 电脑之间传文件可以直接用 `scp`。
上传文件到远端:
```powershell
scp -o PubkeyAuthentication=no .\tdx_link.py Administrator@192.168.1.29:"C:/Temp/tdxdeploy/"
从远端拉文件到本机:
```powershell
scp -o PubkeyAuthentication=no Administrator@192.168.1.29:"C:/Temp/tdxdeploy/tdx_link.py" .
为什么建议用 ASCII 中转目录
Windows 下 `scp` 遇到中文路径时,偶尔会出现路径编码问题。
所以建议采用两步法:
- 先把文件传到远端英文路径 `C:\Temp\tdxdeploy`。
- 再通过远端 PowerShell 复制到真实项目目录。
示例:
```powershell
$script = @'
$src = 'C:\Temp\tdxdeploy'
$dst = 'H:\波段投资回测'
Copy-Item (Join-Path src 'tdx_link.py') -Destination (Join-Path dst 'tdx_link.py') -Force
Copy-Item (Join-Path src 'tdx_remote_server.py') -Destination (Join-Path dst 'tdx_remote_server.py') -Force
Get-Item (Join-Path dst 'tdx_link.py'), (Join-Path dst 'tdx_remote_server.py') |
Select-Object Name,Length,LastWriteTime
'@
enc = \[Convert\]::ToBase64String(\[Text.Encoding\]::Unicode.GetBytes(script))
ssh -o PubkeyAuthentication=no Administrator@192.168.1.29 "powershell -NoProfile -EncodedCommand $enc"
目录传输建议先压缩再传:
```powershell
Compress-Archive -Path .\my_folder -DestinationPath .\my_folder.zip -Force
scp -o PubkeyAuthentication=no .\my_folder.zip Administrator@192.168.1.29:"C:/Temp/tdxdeploy/"
远端解压:
```powershell
ssh -o PubkeyAuthentication=no Administrator@192.168.1.29 `
"powershell -NoProfile -Command Expand-Archive -Path 'C:\Temp\tdxdeploy\my_folder.zip' -DestinationPath 'H:\波段投资回测' -Force"
八、HTTP 服务如何长期运行
`tdx_remote_server.py` 可以直接前台运行:
```powershell
python tdx_remote_server.py
前台运行适合调试,因为可以看到日志。
日常使用更适合放到 Windows 计划任务里,例如任务名:
```text
TDXRemoteLink
计划任务动作建议配置为:
|--------|--------------------------------|
| 项目 | 值 |
|---|---|
| 程序 | Python 解释器绝对路径 |
| 参数 | `tdx_remote_server.py` 的绝对路径 |
| 起始目录 | 项目目录或中转部署目录 |
如果用 SSH 直接启动一个长期进程,SSH 会话关闭后进程可能退出。因此长期服务优先用计划任务或 Windows 服务方式托管。
启动计划任务:
```powershell
ssh -o PubkeyAuthentication=no Administrator@192.168.1.29 `
"powershell -NoProfile -Command Start-ScheduledTask -TaskName 'TDXRemoteLink'"
检查计划任务:
```powershell
ssh -o PubkeyAuthentication=no Administrator@192.168.1.29 `
"powershell -NoProfile -Command Get-ScheduledTask -TaskName 'TDXRemoteLink'"
九、联动测试流程
1. 测试 SSH
```powershell
Test-NetConnection -ComputerName 192.168.1.29 -Port 22
ssh -o PubkeyAuthentication=no Administrator@192.168.1.29 "hostname"
如果 SSH 正常,说明维护链路可用。
2. 测试 HTTP 端口
```powershell
Test-NetConnection -ComputerName 192.168.1.29 -Port 8765
如果端口不通,检查远端 `tdx_remote_server.py` 是否运行、防火墙是否放行。
3. 测试股票联动接口
```powershell
Invoke-RestMethod "http://192.168.1.29:8765/link?code=600519"
观察远端通达信是否切换到贵州茅台。
反向测试:
```powershell
Invoke-RestMethod "http://192.168.1.234:8765/link?code=600519"
观察本机通达信是否切换。
4. 测试实际点击
最后回到选股程序:
- 本机打开选股程序。
- 远端打开通达信和 HTTP 接收服务。
- 本机点击某只股票。
- 观察远端通达信是否自动切换。
- 远端运行同一代码时,点击股票后观察本机是否自动切换。
十、常见故障排查
|------------------|--------------------------------------------------|
| 现象 | 优先检查 |
|---|---|
| SSH 连不上 | `sshd` 服务、防火墙、IP 是否变化、用户名密码是否正确 |
| `22` 端口不通 | 远端 OpenSSH Server 未启动或防火墙未放行 |
| HTTP 接口访问失败 | `tdx_remote_server.py` 没启动、`8765` 被防火墙拦截 |
| 本机点击后远端无反应 | 本机 `tdx_remote_config.json` 的 `hosts` 是否指向远端 |
| HTTP 返回成功但通达信没切换 | 远端通达信是否打开、接收端联动逻辑是否正常 |
| 远端没开机时本机报错 | 检查 `timeout` 是否过长、`verbose` 是否应设为 `false` |
| SCP 中文路径失败 | 使用 `C:\Temp\tdxdeploy` 作为中转目录 |
十一、安全建议
这套方案在局域网内使用已经足够轻量,但仍建议注意安全边界:
- SSH 密码不要写入脚本和文档。
- HTTP 联动端口只在可信局域网内开放。
- 不建议把 `8765` 或 `22` 端口映射到公网。
- 如需长期使用 SSH,建议后续改成密钥登录,并妥善保管私钥。
- 防火墙规则尽量限制在家庭或办公局域网网段。
- 日常配置里保持 `verbose: false`,避免远端离线时干扰选股操作。
十二、最终效果
完成配置后,两台电脑具备三类能力:
|--------|------------|---------------------|
| 能力 | 技术方案 | 典型用途 |
|---|---|---|
| 股票点击联动 | HTTP | 本机点击股票,远端通达信自动切换 |
| 双边联动 | 双端 HTTP 服务 | 任意一台电脑点击,另一台电脑同步 |
| 远程维护 | SSH / SCP | 部署代码、查看日志、复制文件、启动服务 |
这套架构的优势是职责清晰:
```text
HTTP 只传业务事件。
SSH 只做维护操作。
发送端不依赖接收端在线。
接收端独立完成本机通达信联动。
也正因为这几个边界清楚,整套系统在日常办公里会比较稳:一台电脑可以独立使用,两台电脑同时在线时自动形成联动;需要维护时,Codex 或 PowerShell 可以直接通过 SSH 操作远端,不再依赖手动拷贝和来回切屏。