我正在编写一个程序,它要求每隔10毫秒左右从远程服务器获取一个图像,因为这是图像更新的频率。我目前的方法调用一个计时器来抓取图像,但它总是遇到Socket Closed
错误,有时根本不工作。
我如何修复我的方法保持套接字一直打开,所以不需要重新连接?
下面是完整的类:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.Timer;
public class Connection {
public static void createServer() throws IOException {
Capture.getScreen();
ServerSocket socket = null;
try {
socket = new ServerSocket(12345, 0,
InetAddress.getByName("127.0.0.1"));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Server started on "
+ socket.getInetAddress().getHostAddress() + ":"
+ socket.getLocalPort() + ",nWaiting for client to connect.");
final Socket clientConnection = socket.accept();
System.out.println("Client accepted from "
+ clientConnection.getInetAddress().getHostAddress()
+ ", sending file");
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
System.out.println("Sending File");
try {
pipeStreams(new FileInputStream(new File(
"captures/sCap.png")),
clientConnection.getOutputStream(), 1024);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
};
System.out.println("closing out connection");
try {
clientConnection.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
Timer timer = new Timer(10, taskPerformer);
timer.setRepeats(true);
timer.start();
}
public static void createClient() throws IOException {
System.out.println("Connecting to server.");
final Socket socket = new Socket();
try {
socket.connect(new InetSocketAddress(InetAddress
.getByName("127.0.0.1"), 12345));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
}
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
System.out.println("Success, retreiving file.");
try {
pipeStreams(socket.getInputStream(), new FileOutputStream(
new File("captures/rCap.png")), 1024);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
}
}
};
System.out.println("Closing connection");
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
Timer timer = new Timer(10, taskPerformer);
timer.setRepeats(true);
timer.start();
}
public static void pipeStreams(java.io.InputStream source,
java.io.OutputStream destination, int bufferSize)
throws IOException {
byte[] buffer = new byte[bufferSize];
int read = 0;
while ((read = source.read(buffer)) != -1) {
destination.write(buffer, 0, read);
}
destination.flush();
destination.close();
source.close();
}
}
在您的方法pipeStreams
中,您在输入完成后关闭outputStream。如果你想在这个流之后输出另一个流,那么在你完成输出所有内容之前不要关闭它。直接删除行;
destination.close();
看起来你使用相同的方法来发送和接收,所以你需要在接收和输出时独立关闭目的地。你应该意识到你需要定义一个协议,如果你想简单地将2个流连续地管道到同一个客户端,接收方将不知道它期望什么,并将它们视为单个流。一种简单的方法是首先发送一个整数,指定要发送的字节数。然后你的接收器就可以读取这么多字节,在等待一个新的长度之前。