Ruby 从套接字获得响应时冻结
Ruby freezes on getting response from socket
我有一个 Java 服务器 运行,我想使用 Ruby 从中获取信息,但是 Ruby 在收到来自Java 服务器。 (服务器知道 Ruby 连接到服务器并给了服务器字符串)为什么?如果我关闭服务器,Ruby 继续并得到一个空字符串。
Ruby 客户:
#!/usr/bin/env ruby
require 'socket'
sock = TCPSocket.new('some.numeric.ip', 25002)
sock.send('test[=11=]0',0)
puts sock.read #and there Ruby frezees :c
sock.close
Java服务器(下):
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
}
}
}
扩展 Cody S 的评论 - Ruby 读取调用不会 return 直到 TCP 连接关闭。要对此进行测试,请将 Ruby 读取调用更改为 sock.read(4)
。这样调用就会return当它收到4个字节时,不管连接是否关闭。
如果可行,则启动 Wireshark 并查看 Java 服务器是否正在关闭 TCP 连接。要找出网络上正在发送的内容,Wireshark 是您的好帮手。
你的缩进太乱了,你不值得回答。为什么?因为需要 20 分钟才能修复您的格式。
您的代码有两个问题:
这一行:String str = socketReader.readLine();
表示从套接字读取数据直到遇到换行符(换行符可以是"\n"
、"\r"
或"\r\n"
)。然而在你的 ruby 程序中,你这样做:sock.send('test[=14=]0',0)
。该数据中的任何地方都没有换行符,因此您的 java 程序耐心地坐在那里尝试读取更多数据。
修复#1 后,您的服务器将输出错误:java.net.SocketException: Socket closed
。那是因为 socketReader.close();
也关闭了底层套接字。随后,任何尝试使用套接字的代码都会抛出错误。关闭 java 代码中的套接字也会导致 ruby 客户端中的 sock.read
行变为 return 而没有读取任何内容,因此 [=35= 不会输出任何内容] 客户.
我有一个 Java 服务器 运行,我想使用 Ruby 从中获取信息,但是 Ruby 在收到来自Java 服务器。 (服务器知道 Ruby 连接到服务器并给了服务器字符串)为什么?如果我关闭服务器,Ruby 继续并得到一个空字符串。
Ruby 客户:
#!/usr/bin/env ruby
require 'socket'
sock = TCPSocket.new('some.numeric.ip', 25002)
sock.send('test[=11=]0',0)
puts sock.read #and there Ruby frezees :c
sock.close
Java服务器(下):
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
}
}
}
扩展 Cody S 的评论 - Ruby 读取调用不会 return 直到 TCP 连接关闭。要对此进行测试,请将 Ruby 读取调用更改为 sock.read(4)
。这样调用就会return当它收到4个字节时,不管连接是否关闭。
如果可行,则启动 Wireshark 并查看 Java 服务器是否正在关闭 TCP 连接。要找出网络上正在发送的内容,Wireshark 是您的好帮手。
你的缩进太乱了,你不值得回答。为什么?因为需要 20 分钟才能修复您的格式。
您的代码有两个问题:
这一行:
String str = socketReader.readLine();
表示从套接字读取数据直到遇到换行符(换行符可以是"\n"
、"\r"
或"\r\n"
)。然而在你的 ruby 程序中,你这样做:sock.send('test[=14=]0',0)
。该数据中的任何地方都没有换行符,因此您的 java 程序耐心地坐在那里尝试读取更多数据。修复#1 后,您的服务器将输出错误:
java.net.SocketException: Socket closed
。那是因为socketReader.close();
也关闭了底层套接字。随后,任何尝试使用套接字的代码都会抛出错误。关闭 java 代码中的套接字也会导致 ruby 客户端中的sock.read
行变为 return 而没有读取任何内容,因此 [=35= 不会输出任何内容] 客户.