通过套接字发送文件

发布于 2024-11-08 20:24:05 字数 711 浏览 0 评论 0原文

你好,我正在尝试使用 java 中的客户端-服务器类发送文件。由于某种原因,当调用发送文件的方法时,套接字会关闭。这是代码:

FileInputStream fIn = new FileInputStream(file);
out = new BufferedOutputStream(clientSocket.getOutputStream());
byte fileContent[] = new byte[(int) file.length()];
fIn.read(fileContent);
for (byte b : fileContent) {
    out.write(b);
}

以及来自客户端的代码:

FileOutputStream fIn = new FileOutputStream("testing");
BufferedInputStream inAout = new BufferedInputStream(clientSocket.getInputStream());
byte fileContent[] = new byte[1000000];
inAout.read(fileContent);
fIn.write(fileContent);

以及我收到的错误消息:SEVERE:null java.net.SocketException:套接字关闭

我对此并没有真正的经验,所以如果有任何可以帮助的话那就太好了。

Hello there im trying to send files using client-server classes in java. For some reason when the method that sends the file is called the socket closes. here is the code :

FileInputStream fIn = new FileInputStream(file);
out = new BufferedOutputStream(clientSocket.getOutputStream());
byte fileContent[] = new byte[(int) file.length()];
fIn.read(fileContent);
for (byte b : fileContent) {
    out.write(b);
}

and the code from the client :

FileOutputStream fIn = new FileOutputStream("testing");
BufferedInputStream inAout = new BufferedInputStream(clientSocket.getInputStream());
byte fileContent[] = new byte[1000000];
inAout.read(fileContent);
fIn.write(fileContent);

and the error message i get : SEVERE: null
java.net.SocketException: Socket closed

Im not really experienced with this so if any can help it would be great.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

野侃 2024-11-15 20:24:05

InputStream.read(byte[]) 方法返回一个 int 来表示它实际读取的字节数。不能保证从字节数组中读取您请求的字节数。它通常会返回底层缓冲区的大小,您必须多次调用它。

您可以通过将字节从套接字流式传输到文件而不是在内存中缓冲整个字节数组来提高效率。同样,在服务器端,您可以执行相同的操作来节省内存,并且比一次写入一个字节更快。

以下是服务器和客户端连接到自身以传输文件的工作示例:

public class SocketFileExample {
    static void server() throws IOException {
        ServerSocket ss = new ServerSocket(3434);
        Socket socket = ss.accept();
        InputStream in = new FileInputStream("send.jpg");
        OutputStream out = socket.getOutputStream();
        copy(in, out);
        out.close();
        in.close();
    }

    static void client() throws IOException {
        Socket socket = new Socket("localhost", 3434);
        InputStream in = socket.getInputStream();
        OutputStream out = new FileOutputStream("recv.jpg");
        copy(in, out);
        out.close();
        in.close();
    }

    static void copy(InputStream in, OutputStream out) throws IOException {
        byte[] buf = new byte[8192];
        int len = 0;
        while ((len = in.read(buf)) != -1) {
            out.write(buf, 0, len);
        }
    }

    public static void main(String[] args) throws IOException {
        new Thread() {
            public void run() {
                try {
                    server();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();

        client();
    }
}

The InputStream.read(byte[]) method returns an int for the number of bytes it actually read. It's not guaranteed to read as many bytes as you requested from the byte array. It'll often return the size of the underlying buffer and you'll have to call it many times.

You can use this to be more efficient by streaming the bytes from the socket to the file instead of buffering the whole byte array in memory. Likewise on the server side you can do the same thing to save memory and be faster than writing a byte at a time.

Here's a working example of a server and client in one that connects to itself to transfer a file:

public class SocketFileExample {
    static void server() throws IOException {
        ServerSocket ss = new ServerSocket(3434);
        Socket socket = ss.accept();
        InputStream in = new FileInputStream("send.jpg");
        OutputStream out = socket.getOutputStream();
        copy(in, out);
        out.close();
        in.close();
    }

    static void client() throws IOException {
        Socket socket = new Socket("localhost", 3434);
        InputStream in = socket.getInputStream();
        OutputStream out = new FileOutputStream("recv.jpg");
        copy(in, out);
        out.close();
        in.close();
    }

    static void copy(InputStream in, OutputStream out) throws IOException {
        byte[] buf = new byte[8192];
        int len = 0;
        while ((len = in.read(buf)) != -1) {
            out.write(buf, 0, len);
        }
    }

    public static void main(String[] args) throws IOException {
        new Thread() {
            public void run() {
                try {
                    server();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();

        client();
    }
}
暖树树初阳… 2024-11-15 20:24:05

原因非常简单:调用 inAout.read(fileContent) 将在传输大约 4KB 的数据后返回。这是输入缓冲区的大小。因此,您不需要一次巨大的读取,而是需要一个循环和多次读取,并将与从套接字获取的字节数一样多的字节写入fIn

另外不要忘记刷新服务器端的输出(关闭将刷新它),否则一些数据将丢失。

The reason is pretty simple: The call inAout.read(fileContent) will return after about 4KB of data has been transmitted. That's the input buffer size. So instead of a single huge read, you need a loop and many reads and write as many bytes to fIn as you got from the socket.

Also don't forget to flush the output on the server side (closing will flush it) or some data will be lost.

甜点 2024-11-15 20:24:05
SEVERE: null java.net.SocketException: Socket closed

这意味着您自己关闭了套接字,然后调用了另一个需要打开它的操作。例如,关闭套接字或其输入流或输出流会关闭另一个流和套接字。你在某个地方正在这样做。

SEVERE: null java.net.SocketException: Socket closed

That means you've closed the socket yourself and then called another operation that needs it open. For example, closing the socket or its input stream or output stream closes the other stream and the socket. Somewhere or other you are doing that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文