Java IO 服务器客户机读取和处理用户输入



我有一个简单的文件服务器和客户端(来自网络的代码),可以让我将文件发送到我家局域网内的另一台笔记本电脑。现在,从服务器发送到客户端的文件是硬编码的,但我想提示客户端的用户输入文件名,将其发送到服务器并发回指定的文件。我的代码如下所示:

服务器

import java.net.*;
import java.io.*;
public class Server {  
    public static void main(String[] args) {
        BufferedOutputStream outputStream;
        BufferedInputStream inputStream;
        FileInputStream fileInput;
        String file = "C:/java/file.mp4";
        try {
            ServerSocket socket = new ServerSocket(12345); 
            while(true) { 
                Socket clientSocket = socket.accept();
                outputStream = new BufferedOutputStream(clientSocket.getOutputStream());
                fileInput = new FileInputStream(file);
                inputStream = new BufferedInputStream(fileInput);
                int packetToSend = -1;
                byte[] buffer = new byte[8192];
                while((packetToSend = inputStream.read(buffer)) > -1) { 
                    outputStream.write(buffer, 0, packetToSend);
                    System.out.println("sending " + packetToSend + " bytes");
                    outputStream.flush();
                }
            }
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }
}

这就是客户端代码(服务器的 IPA地址是参数 s[0],保存文件的路径是 main 方法中的 s[1]。

import java.net.*;
import java.io.*;
public class Client {
    public static void main(String[] s) {
        try { 
            String address = new String(s[0]);
            String fileToSave = new String(s[1]); 
            Socket socket = new Socket(address,12345);
            BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
            BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
            FileOutputStream fos = new FileOutputStream(fileToSave);
            int n;
            byte[] buffer = new byte[8192];
            System.out.println("Connected");    
            while ((n = bis.read(buffer)) > 0) {
                System.out.println("received "+n+" bytes");
                fos.write(buffer, 0, n);
                fos.flush();
            }
            System.out.println("recieved");
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }
}

我想让客户端的用户在客户端连接后输入文件名以发送到服务器,服务器应该发送该文件。

我试图在System.out.println("connected");后将其放在客户端

System.out.print("Insert filename to download: ");
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String input = null;
    try {
       input = reader.readLine();
    } catch (IOException ioe) {
       System.out.println("Eingabe konnte nicht verarbeitet werden!");
       System.exit(1);
    }
    System.out.println("Eingabe: " + input);

在服务器端,我将其放在outputStream = new BufferedOutputStream(clientSocket.getOutputStream());之后,以覆盖服务器类开头的硬编码文件名。

        inputStream = new BufferedInputStream(clientSocket.getInputStream());
        fileInputStream = new FileInputStream(inputStream);
        fileInputStream = new BufferedInputStream(fileInput);
建立连接后

,客户端处于空闲状态(无法输入某些内容),服务器端在写出控制台"新连接"后不执行任何操作。

请问我该如何解决这个问题?

客户端将文件名发送到服务器。 因此,首先您必须从套接字的输入流中提取文件名。 为此,您需要为如何发送信息建立一个协议。 这在处理 TCP 流时至关重要,这与 UDP 数据报不同。 通常使用两个换行符来传达消息的结尾。 但是由于文件名中有一个换行符是不正常的,我们将使用一个换行符来传达消息的结尾。

然后,我们可以使用 Scanner 从客户端的套接字中提取文件名。

String fileName;
Scanner scanner = new Scanner (clientSocket.getInputStream());
while(scanner.hasNextLine())
{
    fileName = scanner.nextLine();
    break;
}
fileInputStream = new FileInputStream(fileName);
fileInputStream = new BufferedInputStream(fileInput);

在此示例中,文件名必须是该文件的绝对路径,因为它位于服务器的文件系统中。 在将来的版本中,您可能希望在存储文件的服务器上使用目录,客户端可以为您提供该目录中文件的相对路径。 这是它的样子。

String fileName;
Scanner scanner = new Scanner (clientSocket.getInputStream());
while(scanner.hasNextLine())
{
    fileName = scanner.nextLine();
    break;
}
fileInputStream = new FileInputStream(FILE_DIR + fileName);
fileInputStream = new BufferedInputStream(fileInput);

变量FILE_DIR如下所示:

static String FILE_DIR = "C:/java/";

客户端发送的文件将file.mp4

编辑 1:

下面是包含建议的客户端代码。 请注意,此测试质量代码,而不是生产代码。

import java.net.*;
import java.io.*;
public class Client {
    static String FILE_DIR = "./";
    public static void main(String[] s) throws IOException {
        /**
         * Establish socket using main args.
         */
        String address = s[0];
        while (true) {
            /**
             * Get the file name from the user.
             */
            System.out.print("Insert filename to download: ");
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String fileName = null;
            try {
                fileName = reader.readLine();
            } catch (IOException ioe) {
                System.out.println("Eingabe konnte nicht verarbeitet werden!");
                System.exit(1);
            }
            System.out.println("Eingabe: " + fileName);
            /**
             * Create the socket.
             */
            Socket socket = new Socket(address, 12345);
            /**
             * With file name in hand, proceed to send the filename to the
             * server.
             */
            //...put in try-with-resources to close the outputstream.
            try (BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream())) {
                System.out.println("Connected:  Sending file name to server.");
                //...send file name plus a newline.
                bos.write((fileName + 'n').getBytes());
                bos.flush();
            /**
             * Get the file contents and save to disk.
             */
            //...wrap input stream in DataInpuStream for portability.
            //...put in try-with-resource to close the input stream.
            try (BufferedInputStream bis = new BufferedInputStream(new DataInputStream(socket.getInputStream()))) {
                DataOutputStream fos = new DataOutputStream(new FileOutputStream(fileName));
                int n;
                byte[] buffer = new byte[8192];
                System.out.println("Connected:  Recieving file contents from server.");
                while ((n = bis.read(buffer)) > 0) {
                    System.out.println("received " + n + " bytes");
                    fos.write(buffer, 0, n);
                    fos.flush();
                }
                System.out.println("recieved");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
     }
    }
}

这是服务器代码。 请注意,服务器正在从名为./files/的本地目录中检索文件,请将其更改为所需的任何目录。

导入 java.net。;进口 java.io.;import java.util.Scanner;

公共类服务器 {

static String FILE_DIR = "./files/";
public static void main(String[] args) {
    BufferedInputStream inputStream;
    FileInputStream fileInput;
    try {
        ServerSocket socket = new ServerSocket(12345);
        while (true) {
            Socket clientSocket = socket.accept();
            /**
             * Get the file name from the client. File name is one per line.
             */
            //...put in trye-with-resources to close InputStream for us.
            try (InputStream inputFromClient = clientSocket.getInputStream()) {
                System.out.println("Connected:  Getting file name from client.");
                Scanner scanner = new Scanner(inputFromClient);
                String fileName;
                if (scanner.hasNextLine()) {
                    fileName = scanner.nextLine();
                    System.out.println("File name = " + fileName);
                } else {
                    //...no line found, continue.  consider logging an error or warning.
                    continue;
                }
                /**
                 * With fileName in hand, we can proceed to send the
                 * contents of the file to the client.
                 */
                fileInput = new FileInputStream(fileName);
                //...use DataInputStream for more portable code
                DataInputStream dataInput = new DataInputStream(fileInput);
                inputStream = new BufferedInputStream(dataInput);
                int packetToSend = -1;
                byte[] buffer = new byte[8192];
                //...consider closing the OutputStream to let the client know.
                //...use try-with-resource to close the outputStream for us.
                //...wrap your outputStream in DataOutputStream
                try (BufferedOutputStream outputStream = new BufferedOutputStream(new DataOutputStream(clientSocket.getOutputStream()))) {
                    while ((packetToSend = inputStream.read(buffer)) > -1) {
                        outputStream.write(buffer, 0, packetToSend);
                        System.out.println("sending " + packetToSend + " bytes");
                        outputStream.flush();
                    }
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

最新更新