保持套接字打开,以便在定时器调用时发送文件



我正在编写一个程序,它要求每隔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个流连续地管道到同一个客户端,接收方将不知道它期望什么,并将它们视为单个流。一种简单的方法是首先发送一个整数,指定要发送的字节数。然后你的接收器就可以读取这么多字节,在等待一个新的长度之前。

最新更新