【发布时间】:2014-04-07 10:37:25
【问题描述】:
我正在用 Java 编写一个简单的 TCP 客户端/服务器程序对,如果客户端在 10 秒内没有发送任何内容,则服务器必须断开连接。 socket.setSoTimeout() 让我明白了,服务器断开连接就好了。问题是 - 我怎样才能让客户端确定服务器是否关闭?目前我正在使用 DataOutputStream 写入服务器,这里的一些答案表明写入关闭的套接字会抛出 IOException,但这不会发生。
我应该使用哪种写入器对象来向服务器发送任意字节块,这会引发异常或以其他方式指示连接已远程关闭?
编辑:这是客户端代码。这是一个测试函数,它从文件系统中读取一个文件并将其发送到服务器。它以块的形式发送它,并在每个块之间暂停一段时间。
public static void sendFileWithTimeout(String file, String address, int dataPacketSize, int timeout) {
Socket connectionToServer = null;
DataOutputStream outStream = null;
FileInputStream inStream = null;
try {
connectionToServer = new Socket(address, 2233);
outStream = new DataOutputStream(connectionToServer.getOutputStream());
Path fileObject = Paths.get(file);
outStream.writeUTF(fileObject.getFileName().toString());
byte[] data = new byte[dataPacketSize];
inStream = new FileInputStream(fileObject.toFile());
boolean fileFinished = false;
while (!fileFinished) {
int bytesRead = inStream.read(data);
if (bytesRead == -1) {
fileFinished = true;
} else {
outStream.write(data, 0, bytesRead);
System.out.println("Thread " + Thread.currentThread().getName() + " wrote " + bytesRead + " bytes.");
Thread.sleep(timeout);
}
}
} catch (IOException | InterruptedException e) {
System.out.println("Something something.");
throw new RuntimeException("Problem sending data to server.", e);
} finally {
TCPUtil.silentCloseObject(inStream);
TCPUtil.silentCloseObject(outStream);
TCPUtil.silentCloseObject(connectionToServer);
}
}
我希望 outStream.write 在尝试写入已关闭的服务器时抛出 IOException,但什么也没有。
【问题讨论】:
-
“但这不会发生”。那么服务器关闭时发生了什么?
-
当服务器关闭套接字时,您的客户端输入流将指示该流已关闭。如果你碰巧在服务器关闭套接字的同时写入输出流,你也应该得到一个异常。不知道为什么你没有得到例外。你能显示一些代码吗?
-
@CHOCKO - 几乎没有。客户端将数据写入流并正常退出,而不关心服务器不再在那里读取数据。