我们希望构建与文件和URL关联的Java应用程序,但一次只能运行一个实例。如果打开了第二个文件,则应由已运行的实例(如果可用)处理。 (将其视为文件查看器:用户单击浏览器中的链接可打开应用程序,单击第二个链接会将相同的应用程序置于前端,并在新视图中打开第二个URL。)
为此,我的计划是:
app file1.ext
。这将启动第一个实例。file1.ext
。app file2.ext
。这将启动第二个实例。file2.ext
。file2.ext
并确认。我可以想到用于实现通信通道的各种技术,但它们都在本地计算机上打开一个端口。这很好,但我想确保只有当前用户可以使用此端口。我可能会阻止第二个用户意外地向第一个用户的应用程序发送命令,但是如何强制执行用于进程间通信的端口或其他任何内容仅对启动第一个应用程序的用户可用启动?
解决方案应尽可能与平台无关。
答案 0 :(得分:2)
您可以使用锁定/ pid文件,程序应检查锁定文件是否存在以查找是否存在现有进程。锁定文件应包含它正在侦听的端口号,服务器密钥和会话密钥。您需要设置文件权限,以便当前用户只能读取。初始进程的所有消息都必须包含匹配的会话密钥。会话密钥证明发起进程具有读取锁文件的权限,因此您的开放端口会继承锁文件的权限。
为了安全起见,您需要注意打开端口并写入锁定文件的顺序。您需要确保在写入锁定文件之前打开端口,否则恶意程序可能会超出服务器并接收无法读取的消息。此外,第二个进程应检查锁定文件的所有者,以确保它是由当前用户创建的。此外,在第二个进程开始发送数据之前,您还应该检查服务器在其握手中返回服务器密钥,以确保当前运行的服务器实际上也具有对锁定文件的读取权限,因为服务器可能已经很久了,取而代之的是恶意程序。最后,确保程序仅绑定到本地连接,除非您确实要允许来自网络的请求。
如果这是一个只支持Linux / Unix / Mac的程序,那么你还可以选择打开一个Unix域套接字。您应该为域套接字设置文件权限,以便它只能由当前用户读/写。如果使用域套接字,则不需要会话密钥或所有这些握手,因为域套接字的权限是由域套接字的文件权限强制执行的。