Ruby冻结从socket获得响应

时间:2015-04-03 23:41:37

标签: java ruby-on-rails ruby sockets server

我正在运行Java Server,并且我想使用Ruby从中获取信息,但Ruby在从Java Server获得响应时会冻结。 (服务器知道Ruby连接到服务器并给出了服务器字符串)为什么?如果我关闭服务器,Ruby会继续并获得一个空字符串。

Ruby客户端:

#!/usr/bin/env ruby
require 'socket'
sock = TCPSocket.new('some.numeric.ip', 25002)
sock.send('test\000',0)
puts sock.read #and there Ruby frezees :c
sock.close

Java Server(下面):

public class kRcon{
    private static Socket socket;
    private static ServerSocket serverSocket;
    private static Thread u;

    private static class Server extends Thread {
            public void run() {
                    int port = 25002;
                    try {
                        serverSocket = new ServerSocket(port);
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                    while(true) {
                      try {
                         socket = serverSocket.accept();
                         BufferedReader socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                         BufferedWriter socketWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                         String str = socketReader.readLine();
                    socketReader.close();
                         System.out.println(str);
                         socketWriter.write("test");
                         socketWriter.flush();
                         socketWriter.close();
                      }
                    }catch (IOException e1) {
                        e1.printStackTrace();
                    }
           }
     public static void init(){
       try {
          u = new Server();
          u.setName("Server");
          u.start();
       } catch (IOException e) {
          System.out.println(e.getMessage()); // changed
      }
   }
}

2 个答案:

答案 0 :(得分:0)

扩展Cody S的评论 - 在TCP连接关闭之前,Ruby读取调用不会返回。要对此进行测试,请将Ruby读取调用更改为sock.read(4)。这样,无论连接是否关闭,调用将在收到4个字节时返回。

如果这样做,那么启动Wireshark并查看Java服务器是否正在关闭TCP连接。当找到网络上发送的内容时,Wireshark就是你的朋友。

答案 1 :(得分:0)

你的缩进是如此搞砸了,你不值得回答。为什么?因为需要20分钟才能修复您的格式。

您的代码有两个问题:

  1. 这一行:String str = socketReader.readLine();表示从套接字读取数据,直到遇到换行符(换行符可以是"\n""\r"或{{1}中的任意一行})。但是在你的ruby程序中,你这样做:"\r\n"。该数据中没有任何换行符,因此您的java程序耐心地坐在那里尝试读取更多数据。

  2. 修复#1后,您的服务器将输出错误:sock.send('test\000',0)。那是因为java.net.SocketException: Socket closed也关闭了底层套接字。随后,任何试图使用套接字的代码都会抛出错误。在java代码中关闭套接字也会导致ruby客户端中的行socketReader.close();在没有读取任何内容的情况下返回,因此ruby客户端不会输出任何内容。