0

サーバーからクライアントにファイルを送信しようとすると、問題が発生します。サーバーからクライアントに同じファイルを2つの別々のファイルに送信できないようです。代わりに、最初のファイルの末尾に追加するだけです! どんな助けでも大歓迎です。

編集: コードを変更しました。ファイルの送受信タスクを「sendfile」と「recievefile」の 2 つの関数にモジュール化しました。私が今得ているエラーは、2 回目の呼び出しの後に sendfile および recievefile 関数でソケットが閉じられていることです。しかし、私が閉じているのは、ファイルと出力ストリームと入力ストリームだけです! おそらく、これらのストリームを閉じるとソケットも閉じられます...? とにかく、入力ストリームと出力ストリームを閉じないようにしましたが、何が起こるか - 1) 宛先ファイルに何も転送されません。したがって、サーバー側で空白に作成されたファイルを取得するだけです。2) 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

ファイルを送信するときは、一方を他方の末尾に追加するだけなので、クライアントはファイルを見ることができます。

1つのファイルの読み取りを停止し、2番目のファイルの読み取りを開始するタイミングをクライアントに通知する必要があります。

最も簡単なアプローチは、ファイルの長さをファイルの前に送信し、データの量よりも正確に読み取ることです。

ところで:バイナリストリームとテキストストリームを今のように組み合わせることができません。これは混乱を招く可能性が高くなります。あなたの場合、バイナリを送信する必要があるので、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 に答える