【问题标题】:TCPSocket connection cloing issue in RubyRuby中的TCPSocket连接关闭问题
【发布时间】:2015-05-28 08:12:25
【问题描述】:

我是 Ruby 的新手,我正在尝试实现线程,但现在我遇到了一个错误:客户端不明白连接已关闭。

之前,我用 C++ 编写了一个简单的 tcp 客户端-服务器应用程序,该应用程序工作正常:如果服务器关闭连接,客户端表示连接也已关闭。但在 Ruby 中(作为客户端)什么也没有发生,然后应用程序退出并出现错误:

main.rb:34:in `write': Broken pipe (Errno::EPIPE)
    from main.rb:34:in `puts'
    from main.rb:34:in `block (2 levels) in send'
    from main.rb:32:in `loop'
    from main.rb:32:in `block in send'

所以,这里是 C++ 应用程序源文件的一部分。如您所见,如果iResult 等于0,则表示服务器已关闭连接。

if (iResult > 0) {
    std::string recievedString(recvbuf, recvbuf + iResult);
    std::cout << recievedString;
}
else if (iResult == 0) {
    std::cout << "Connection closed." << std::endl;
    break;
}

而且效果很好。

有 Ruby 服务器-客户端 tcp 应用程序:

客户端应用 是的,对不起这些愚蠢的方法..

#!/usr/bin/env ruby -w
require "socket"
class Client
  def initialize( server )
    @server = server
    @request = nil
    @response = nil
    listen
    send
    @request.join
    @response.join
  end

  def listen
    @response = Thread.new do
      loop {
        msg = @server.gets.chomp
        if msg == ""
          Thread.kill(@request)
          Thread.kill(@response)
        else
          puts msg
        end

      }
    end
  end

  def send
    puts "Enter the username:"
    @request = Thread.new do
      loop {
        msg = $stdin.gets.chomp
        @server.puts( msg )
      }
    end
  end
end

server = TCPSocket.open( "127.0.0.1", 6666 )
Client.new( server )

服务器应用

#!/usr/bin/env ruby -w
require "socket"
class Server
  def initialize( port, ip )
    @server = TCPServer.open( ip, port )
    @connections = Hash.new
    @clients = Hash.new
    @connections[:server] = @server
    @connections[:clients] = @clients
    run
  end

  def run  
    loop {
      Thread.start(@server.accept) do | client |
        nick_name = client.gets.chomp.to_sym 
        puts nick_name
        @connections[:clients][nick_name] = client
        puts @connections.inspect
        client.puts "0001"
        listen_user_messages(nick_name, client)
        client.close
        Thread.kill self
      end
    }

  end

  def listen_user_messages( username, client )
    loop {
      msg = client.gets.chomp
      if msg == "0002"
        command = "Yah, two"
      else
        command = "Go home"
      end
      client.puts command
      break
    }
  end
end

Server.new( 6666, "127.0.0.1")

【问题讨论】:

    标签: ruby multithreading tcp network-programming


    【解决方案1】:

    当 TCPSocket 对象关闭时,对.gets 的调用将返回nil。这意味着您的@server.gets.chomp 将引发错误(NoMethodError)并且线程将终止。要处理这种情况,您需要检查套接字的 .gets 调用的返回值。

      def listen
        @response = Thread.new do
          loop {
            msg = @server.gets
            if msg.nil?
              Thread.kill(@request)
              Thread.kill(@response)
            else
              puts msg.chomp
            end
          }
        end
      end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-10
      • 2011-02-17
      相关资源
      最近更新 更多