下面都是必要的关键步骤了,耐心跟着实现是没问题的
方案1——tailscale(适合办公,不适合游戏)
01 实现
参考系统自带“远程桌面”到底该怎么用?为何如此流畅?_哔哩哔哩_bilibili及其评论区
两台电脑同时下载Download | Tailscale这个软件,然后选择同一个微软账户登录(需要有密码设置),查看自己被控电脑win10系统登录的用户名和密码(一定要有相应的win10登录密码),被控电脑开启远程桌面控制(在系统设置那里,桌面右键-显示设置)
接着主控电脑搜索远程桌面连接,点击左下角的更多选项,把tailscale网页登录显示的被控电脑的ip地址作为账户名、而用户名则是被控电脑的登录用户名,接着如果弹出要输入密码的弹窗说明成功了,然后输入登录密码就能远程控屏。
限制:
- win10家庭版不支持开启远程控屏,被控电脑必须是专业版的,否则要额外进行处理
- 安装tailscale时必须要科学上网
- 不支持双方同时启用电脑,只能被控端不操作,所以只适合特定人群的需求,如果有急用帮助客户远程的需求(回答学生问题也是经常多备几个远程软件),还是建议下载远程软件
最大的缺点:
因为不支持N卡!无法打开一些特定需要GPU渲染的游戏,会显示黑屏,尤其是3a大作最明显
优点:
- 免费,没有时长限制
- 相较于一些远程控屏软件,高清画质
- 不需要担心被控端电脑显示屏关闭或锁屏导致一些应用软件出现黑屏问题出现
02 增加电脑的定时启动和定时关机的额外处理
让我们继续加需求,如果被控端的电脑实现了定时自动开机和关机,那么每一次登录都需要开机密码,如果没进入那么就无法启动tailscale,这样就不能远程桌面控制了。
如何实现定时开机?被控电脑登录开机之前按住delelte,然后进入高级电源管理,开启电源并启用ric,设置时间即可,具体参考
【定时开关机】windows 10 如何设置定时开关机_windows定时开机-CSDN博客
需要注意
bios的设置有概率不会成功,这时候就需要到电脑的电源和休眠那里进行如下设置
所以win+r打开 netplwiz
→ 取消勾选「要使用本计算机,用户必须输入用户名和密码」→ 设置自动登录账户。
如果没有「要使用本计算机,用户必须输入用户名和密码」这个选项,那么解决该问题的方法其实非常简单,打开win+r“运行”输入“regedit”,进入“注册表编辑器”,打开如下路径:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device
双击右侧的“DevicePasswordLessBuildVersion”,将值由2改为0
然后重新取消勾选即可,这样就能实现被控电脑自动登录和关机需求之后,也不影响主控电脑的远程桌面控制(还是要输入密码远程控制的)
方案2——sunshine+moonlight+ipv6(推荐)
01 参考
参考使用sunshine和moonlight实现远程游戏串流_moonlight游戏串流软件-CSDN博客
SunShine+moonlight+IPv6公网串流教程 - 哔哩哔哩
缺点:
ipv6地址存在租期,过几天电脑会自动更改,这时候建议备用一个远程软件,可以直接去改域名所需的ipv6地址
另一个缺点则是如果用远程电脑上网看视频会出现失声问题,远程电脑本地端如果音响外放也会出现音频失声问题
优点:
能获得最好的游戏体验
02 实操
你需要安装python
发布 ·LizardByte/阳光被控电脑安装这个(用最新版,不要下预览版),会弹出登录页面,很关键,要记住密码和账号名,然后注册登录进入,否则要卸载重新设置
发布 ·月光流/月光-QT主控电脑用这个
然后进入免费的域名网站No-IP | Smarter DNS Starts Here,左侧栏的No-Ip Hostnames进行create hostname操作。
这个网站会确认是否超过30天没有更换域名信息
创建的时候,根据本地电脑cmd的ipconfig/all命令获得的ipv6地址、ipv4地址写入,hostname随便自己写,这就是到时候moonlight要使用的域名——总之你的域名很重要。
接着在被控电脑中直接使用如下py代码,这里为了测试暂时双击运行脚本
如果你的电脑存在有线和无线网卡,下面py优先获取有线的ipv6地址,因此如果你的情况符合,你需要额外创建多一个专门处理无线的域名,这样也可以测试未来有没有可能是因为网络问题,还是其他原因造成了无法远程控制的情况。
import socket
import base64
import os
import re
import time
class netParam:
def __init__(self):
self.host = "xxx"
self.usrname = "xxx"
self.passwd = "xxx"
self.domain = "xxx"
self.timeval = 10 * 60
self.server_port = 80
def getIPv6Address():
host_ipv6=[]
ips=socket.getaddrinfo(socket.gethostname(),80)
for ip in ips:
if ip[4][0].startswith('24'):
# 2408 中国联通
# 2409 中国移动
# 240e 中国电信
return ip[4][0]
def getip(domain):
address = socket.getaddrinfo(domain, 'http')
return address[0][4][0]
if __name__ == "__main__":
param = netParam()
tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 不经过WAIT_TIME,直接关闭
tcp_sock.setblocking(False) # 设置非阻塞编程
tcp_sock.settimeout(1)
link_statu = False
send_data_len = 0
old_ipv6addr = ""
fisrt_flag = True
# 按协议,对usrname:passwd进行base64编码
raw_key = param.usrname + ":" + param.passwd
print("raw key: " + raw_key)
encode_key = base64.b64encode(raw_key.encode("utf-8"))
encode_key = str(encode_key)[2:len(str(encode_key)) - 1]
print("encode key: " + encode_key)
#构造请求头部的内容,由于本机ip可能变化,因此这里没有直接把GET方法写进去,而是放在循环体中做
requestParam = ""
requestParam += "Host: dynupdate.no-ip.com\r\n"
requestParam += "Authorization: Basic " + encode_key + "\r\n"
requestParam += "User-Agent: None\r\n\r\n"
print("request:\n" + requestParam)
while(True):
# 每次运行等待timeval(此处是5分钟)的间隔,避免频繁更新
if (True != fisrt_flag):
time.sleep(param.timeval)
fisrt_flag = False
# 获取ipv6地址,若地址没有发生改变,则不上报更新
ipv6addr = getIPv6Address()
if (0 != len(ipv6addr)):
print("ipv6 addr: " + ipv6addr)
if (ipv6addr == old_ipv6addr):
print("ip not change, continue")
continue
# 构造请求的头部GET方法内容
requestHead = "GET "
requestHead += "/nic/update?hostname=" + param.domain + "&myip=" + ipv6addr + " HTTP/1.1\r\n"
# 建立tcp连接
if (False == link_statu):
server_ip = getip(param.host)
print("server ip is :" + server_ip)
try:
tcp_sock.connect((server_ip, param.server_port))
print("connect server success")
link_statu = True
except Exception as err:
print("connect server failed, exception:", err)
continue
# 发送数据
send_data = requestHead + requestParam
send_data_len = 0
while send_data_len < len(send_data):
time.sleep(0.1)
try:
send_data_len += tcp_sock.send(send_data[send_data_len:].encode())
print("send " + str(send_data_len) + " data")
except Exception as err:
print("send data error, exception: ", err)
print("close tcp socket")
tcp_sock.close()
link_statu = False
break
if (send_data_len != len(send_data)):
continue
print("send data:" + send_data)
# 检查结果,更新成功则把当前ip记录为旧ip
if (True == link_statu):
try:
recv_data = tcp_sock.recv(2048)
print("server reply:\n" + str(recv_data))
except Exception as err:
print("recv data error, exception: ", err)
tcp_sock.close()
link_statu = False
if (-1 != str(recv_data).find("HTTP/1.1 200 OK")):
old_ipv6addr = ipv6addr
print("update ip success")
print("end")
进入sunshine如下操作
设置防火墙的tcp和udp的入站规则,以便moonlight可以进入
最后主控电脑进入moonlight,右上角有个加号,点击输入我们自己之前创建的域名就能远程连接了,会要求我们被控电脑输入pin确认是否允许电脑被控,进入sunshine页面的pin界面操作即可。
如果最终远程控屏测试不成功,检查前面的步骤是否有遗漏?
03 开机自启+虚拟屏幕
其实这个虚拟显示器的效果只能做到打开那些程序开发应用软件的时候不会出现黑屏白屏的问题
如果开启需要gpu渲染的游戏,那么还是会出现问题,需要强制开启屏幕
然后为了能够开机自启加个bat自动获取每次开机就会更新的ipv6地址
还有下载两个软件Releases · nomi-san/parsec-vdd下载ParsecVDisplay-v0.45-setup.exe,并双击安装
Releases · HaliComing/parsec-vdd-cli下载parsec-vdd-cli.exe
@echo off
python "D:\RemoteActions\GetPCIpv6.py"
"D:\RemoteActions\parsec-vdd-cli.exe" -a
pause
按下 Win + R 键,然后输入 “taskschd.msc”,按ctrl+shift+ Enter 键以管理员的身份打开任务计划程序
自己根据实际的路径情况操作
接着具体设置定时任务
简单可直接白嫖使用远程软件:
有钱肯定不在乎被人随随便便拿个垃圾画质就买个30多块的订阅吧,这钱真好赚
uu(目前没有时长限制,但是未来难说)
todesk(画质不佳,但是免费时长对于间歇性使用还是够的,如果被控电脑文件资源管理右键操作选项过多,会卡顿)
向日葵(不能久用,会被判定成商用)
免费时长一过就换一个,白嫖才是正道