Ruby Scripting-如何同时运行客户端和服务器程序并收集服务器输出

时间:2017-12-11 15:57:42

标签: ruby scripting client-server

所有。我试图创建一个ruby脚本,在后台初始化并运行服务器程序(通常一直运行),然后运行一次短客户端程序,然后杀死服务器。服务器和客户端都是用C ++编写的,服务器运行在localhost,端口4712上。端口是服务器的命令行参数。必须使用" ./ init_serv"初始化服务器。可执行文件,一旦它开始运行,它必须被输入" user1 password1"通过cin。我想将服务器的输出收集到一个文件中," out.txt"。 这就是我到目前为止所做的:

require 'open3'

userinput = "user1 password1"
outfile = File.new("out.txt","w+")
system("./init_server")
Open3.popen2("./server.exe 4712") do |stdin, stdout, t|    
    stdin.puts(userinput)
    stdin.close
    stdout.each_line { |line| outfile.write(line) }
end


puts "Server now running"
system("./test_client localhost 4712")
Process.kill("SIGINT", t.pid)

我认为" popen2" call会创建一个新的线程来运行服务器程序,但是当我运行它时,程序阻塞(服务器不会退出,除非手动终止)并且永远不会打印现在运行的"服务器"声明。关于如何解决这个问题的任何建议?我对脚本编写起来相当新,所以其他建议也很受欢迎。

提前致谢!

1 个答案:

答案 0 :(得分:0)

问题是通过创建一个新线程来解决的,正如Tom Lord建议的那样。 这是新代码:

require 'open3'

$userinput = "user1 password1"
$outfile = File.new("out.txt","w+")
$processthread = nil
system("./init_server")
thr = Thread.new{
    Open3.popen2("./server.exe 4712") do |stdin, stdout, t|    
        $processthread = t
        stdin.puts($userinput)
        stdin.close
        stdout.each_line { |line| $outfile.write(line) }
        t.join
    end
}

sleep(0.25)
puts "Server now running"
system("./test_client localhost 4712 > clientOut.txt")
Process.kill("SIGINT", $processthread.pid)
Thread.kill(thr)

为了在外部函数和线程之间共享数据,我只是懒得使用全局变量。睡眠(0.25)可以正确初始化套接字。一种hacky解决方案,但它的工作原理! 感谢评论中的帮助。