0

我在尝试将文件从服务器发送到客户端时遇到了一些麻烦。我似乎无法将相同的文件从服务器发送到客户端到两个单独的文件中。相反,它只是附加到第一个文件的末尾!任何帮助,将不胜感激。

编辑:我已经修改了代码。我已将文件发送和接收任务模块化为 2 个函数“sendfile”和“recievefile”。我现在得到的错误是套接字在第二次调用后在 sendfile 和 recievefile 函数处关闭。但我要关闭的只是文件以及输出和输入流!也许关闭这些流也会关闭套接字......?无论如何,我试过不关闭输入和输出流,结果是 - 1)没有任何东西被传输到目标文件。所以我只是在服务器端得到一个空白创建的文件。2)甚至没有创建第二个文件。伟大的。

像往常一样,任何帮助将不胜感激。

服务器:

package com.http.server;
import java.io.*;
import java.net.*;

public class Server
{
    public static void main(String args[])throws Exception
    {
        System.out.println("Server running...");

        /* Listen on port 5555 */

        ServerSocket server = new ServerSocket(5555);

        /* Accept the sk */

        Socket sk = server.accept();

        System.out.println("Server accepted client");


        BufferedReader inReader = new BufferedReader(new InputStreamReader(sk.getInputStream()));
        BufferedWriter outReader = new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));

        /* Read the filename */
        String serverlocation = "C:/Users/Arjun/Desktop/CNW model/HTTP Website/";
        String filename = serverlocation + inReader.readLine();
        if ( !filename.equals("") ){

            /* Reply back to client with READY status */

            outReader.write("READY\n");
            outReader.flush();          
        }

        sendfile(sk, filename);
        sendfile(sk, filename);

        outReader.close();
        inReader.close();


        sk.close();
        server.close();

    }

    public static void sendfile(Socket sk, String filename)
    {
        try{

            OutputStream output = sk.getOutputStream();

        FileInputStream file = new FileInputStream(filename);

        byte[] buffer = new byte[sk.getSendBufferSize()];

        int bytesRead = 0; 

        while((bytesRead = file.read(buffer))>0)
        {
            output.write(buffer,0,bytesRead);
        }

        file.close();  
        output.close();
    }
        catch (Exception ex){
            System.out.println(ex);
        }
        }





    }

客户:

package com.http.client;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

public class Client extends JFrame implements ActionListener {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private JTextField txtFile;

    public static void main(String args[]){

        /* Create and display the client form */

        Client clientForm = new Client();
        clientForm.Display();
    }

    public void Display(){

        JFrame frame = new JFrame();
        frame.setTitle("Client");

        FlowLayout layout = new FlowLayout();
        layout.setAlignment(FlowLayout.LEFT);

        JLabel lblFile = new JLabel("URL:");

        txtFile = new JTextField();
        txtFile.setPreferredSize(new Dimension(150,30));

        JButton btnTransfer = new JButton("Get");
        btnTransfer.addActionListener(this);

        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(layout);
        mainPanel.add(lblFile);
        mainPanel.add(txtFile);
        mainPanel.add(btnTransfer);

        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {

        /* File Open Dialog box allows the user to select a file */

        String filename=txtFile.getText();

        try{

            /* Try to connect to the server on localhost, port 5555 */

            Socket sk = new Socket("localhost", 5555);


            /* Send filename to server */

            OutputStreamWriter outreader = new OutputStreamWriter(sk.getOutputStream());
            outreader.write(filename + "\n");
            outreader.flush();

            /* Get response from server */

            BufferedReader inReader = new BufferedReader(new InputStreamReader(sk.getInputStream()));

            String serverStatus = inReader.readLine(); // Read the first line
            /* If server is ready, receive the file */

            while ( !serverStatus.equals("READY") ){}

                /* Create a new file in the tmp directory using the filename */

               recievefile(sk,filename);
               recievefile(sk,"xx"+filename);


                JOptionPane.showMessageDialog(this, "Transfer complete");


                inReader.close();
                outreader.close();
            sk.close();

        }
        catch (Exception ex){
            /* Catch any errors */
            JOptionPane.showMessageDialog(this, ex.getMessage());
            System.out.println(ex);
        }
    }

    public void recievefile(Socket sk, String filename)
    {
        try{

            InputStream input = sk.getInputStream();

        FileOutputStream wr = new FileOutputStream(new File("C:/tmp/" + new File(filename).getName()));

        byte[] buffer = new byte[sk.getReceiveBufferSize()];
        int bytesReceived = 0;

        while((bytesReceived = input.read(buffer))>0)
        {
            /* Write to the file */
           wr.write(buffer,0,bytesReceived);
        } 
        wr.close();
        input.close();

    }
        catch (Exception ex){
            /* Catch any errors */
            JOptionPane.showMessageDialog(this, ex.getMessage());
            System.out.println(ex);
        }

}




}
4

1 回答 1

5

当您发送文件时,您只是将一个附加到另一个的末尾,以便客户看到它们。

您需要让客户端知道何时停止读取一个文件并开始读取第二个文件。

最简单的方法是在文件之前发送文件的长度,并且只读取比数据量精确的数据。

顺便说一句:您不能像以前那样组合二进制流和文本流。这更容易导致混乱。在您的情况下,您需要发送二进制文件,因此使用 DataInputStream 和 DataOutputStream 将所有内容设为二进制文件。


我的想法是这样的。

public static void sendFile(DataOutput out, String filename) throws IOException {
    FileInputStream fis = new FileInputStream(filename);
    byte[] bytes = new byte[8192];
    try {
        long size = fis.getChannel().size();
        out.writeLong(size);
        for (int len; (len = fis.read(bytes, 0, (int) Math.min(bytes.length, size))) > 0; ) {
            out.write(bytes, 0, len);
            size -= len;
        }
        assert size == 0;
    } finally {
        fis.close();
    }
}

public void receiveFile(DataInput in, String filename) throws IOException {
    long size = in.readLong();
    FileOutputStream fos = new FileOutputStream(filename);
    byte[] bytes = new byte[8192];
    try {
        for (int len; (len = (int) Math.min(size, bytes.length)) > 0; ) {
            in.readFully(bytes, 0, len);
            fos.write(bytes, 0, len);
            size -= len;
        }
    } finally {
        fos.close();
    }
}
于 2012-10-08T13:33:37.407 回答