1

私はチュートリアルに従っています:http://www.tutorialspoint.com/ruby/ruby_socket_programming.htmそしてそれを使って「シンプルクライアント」をセットアップしています。

コードは次のとおりです。

    require 'socket'      # Sockets are in standard library

    hostname = 'localhost'
    port = 2000

    s = TCPSocket.open(host, port)

    while line = s.gets   # Read lines from the socket
      puts line.chop      # And print with platform line terminator
    end
    s.close               # Close the socket when done

単一の s.gets ステートメントを実行すると、サーバーから最初の応答行が返されます。もう一度 s.gets を実行すると、2 番目の応答行が表示されます。ただし、応答の最後に到達して s.gets を実行すると、プログラムはフリーズ状態になります。(これは、Rails コンソールから上記のプログラムをテストした場合です)。コードを実行すると同じことが起こります - while ステートメントが最後の s.gets を実行するときにフリーズが発生します。これを解決する方法についてのアイデアはありますか?

情報: サーバーは、次の C# コードを使用して応答メッセージを送信する C# サーバーです (応答の各行は同じコードを使用し、応答の最終行は他の行とまったく異なる方法で処理されません)。

    socket.Send(Encoding.ASCII.GetBytes(msg + "\r\n"));

したがって、サーバーの「応答の終わり」を適切に解釈しない可能性があるため、クライアントがフリーズすると考えています。何か案は?

4

4 に答える 4

2

ソケットからの nil 値の読み取りに問題があるようです。なぜこれが起こるのかはまだわかりませんが、gets() で Ruby の壊れた TCP ソケットから回復するで提案されているようにセレクターを使用すると、問題が非常にうまく解決されます (彼の答えに賛成票を投じたでしょうが、十分な担当者がいません)。

私が従った解決策は、次のようにメソッドにセレクターを追加することでした:

    def next_line_readable?(socket)
      readfds, writefds, exceptfds = select([socket], nil, nil, 0.1)
      p :r => readfds, :w => writefds, :e => exceptfds
      readfds #Will be nil if next line cannot be read
    end

次に、メインプログラムで次のように使用します。

    socket = TCPSocket.open(host, port)
    while next_line_readable?(socket)
      puts socket.gets.chop
    end
于 2012-06-07T08:13:33.317 に答える
1

これを試して、Rubyでtcpクライアントとサーバーを書いています

def sendto(str)
  begin
     socket.write(str)
    puts "Sent Message to:" +  socket.peeraddr[2]
  rescue Exception=>e
    puts red("Error Make sure the target is connected")
  end
end

4時間まで完全に動作することを確認して から、Rubyベースのサーバーへの接続を切断します

于 2012-09-26T07:09:06.453 に答える
0

の代わりにsocket.readまたはメソッドを使用してみてください。 socket.recvfromsocket.gets

同じ動作ですか?

于 2012-06-06T17:04:27.687 に答える
0

gets の代わりに recv を使用する

   server = TCPServer.new 53492 # Server bound to port 53492
    loop do
      client = server.accept
      ansiString = client.recv(100).chomp
      client.puts result
      client.close
     end

次のようにスレッドに変換することもできます。

   server = TCPServer.new 53492 # Server bound to port 53492
   Thread.start(server.accept) do |client|
      loop do
        client = server.accept
        ansiString = client.recv(100).chomp
        client.puts result
        client.close
      end
    end
于 2019-07-19T08:31:12.677 に答える