簡體   English   中英

Ruby on Rails TCPSocket在客戶端應用程序中凍結,而循環使用gets

[英]Ruby on Rails TCPSocket freezes in Client Application while loop using gets

我按照教程: 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時,我會得到第二個響應行,等等。但是,當我到達響應結束並執行s.gets時,程序將進入凍結狀態。 (這是我從Rails控制台測試上面的程序)。 當我運行代碼時會發生同樣的情況 - 當while語句執行最終的s.gets時會發生凍結。 關於如何解決這個問題的任何想法?

有關信息:服務器是C#服務器,它使用以下C#代碼發送響應消息(響應的每一行使用相同的代碼,並且響應中的最后一行與其他行的處理方式不同):

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

所以我認為客戶端凍結,因為它可能無法正確解釋服務器“響應結束”。 有任何想法嗎?

從套接字讀取nil值似乎有問題。 仍然不確定為什么會發生這種情況,但是當在gets()中從一個破壞的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

試試這個在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的服務器

嘗試使用socket.readsocket.recvfrom方法而不是socket.gets

這是一樣的行為嗎?

使用recv代替gets

   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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM