【问题标题】:Java Socket Multi user chat app with both message (text) and file transfer具有消息(文本)和文件传输的 Java Socket 多用户聊天应用程序
【发布时间】:2023-10-11 06:04:01
【问题描述】:

我是 Java 新手。我正在通过制作一个聊天应用程序来学习套接字和线程编程,其中从客户端发送的消息将被服务器接收,服务器会将其发送给另一个客户端。

服务器是这样工作的。字符串的第一个单词是命令,其余是参数。

发消息的命令 示例:味精 jony 嗨!

这将发送嗨!给客户名字 jony。 //

login tom tom123 // 将使用用户名“tom”和密码“tom123”登录 tom

现在我想添加文件传输。所以一个客户端可以将文件发送到另一个客户端。据我所知,我需要使用 DataInputStream 。在这种情况下,如何让服务器区分以下程序中的文件和文本?或者我可以像“file jony c://abc.txt”一样将 abc.txt 文件发送给 jony?

已编辑:看起来像 handleFile 被调用,但它什么都没有。 (如果像handfleFile()一样在开始时调用hangle文件,它就可以工作;

我做错了什么:(

这是我的服务器代码的一部分。

    private void handleClientSocket() throws IOException, InterruptedException, SQLException {
//        InputStream inputStream = clientSocket.getInputStream();
//        this.outputStream = clientSocket.getOutputStream();
//        DataInputStream inputStream = new DataInputStream(clientSocket.getInputStream());
        this.outputStream = new DataOutputStream(clientSocket.getOutputStream());
        this.inputStream = new DataInputStream(clientSocket.getInputStream());

        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        Connect(); //Connects to databse
//        handleFile();
        while ( (line = reader.readLine()) != null) {
            String[] tokens = StringUtils.split(line);
            if (tokens != null && tokens.length > 0) {
                String cmd = tokens[0];
                if ("quit".equalsIgnoreCase(cmd) || "logoff".equalsIgnoreCase(cmd)) {
                    handleLogOff();
                    break;
                } else if ("login".equalsIgnoreCase(cmd)) {
                    handleLogin(outputStream, tokens);
                } else if ("msg".equalsIgnoreCase(cmd)) {
                    String[] tokenMsg = StringUtils.split(line, null, 3);
                    handleMessage(tokenMsg);
                } else if ("join".equalsIgnoreCase(cmd)) {
                    handleJoin(tokens);
                } else if ("leave".equalsIgnoreCase(cmd)) {
                    handleLeave(tokens);
                } else if ("signup".equalsIgnoreCase(cmd)) {
                    handleSignUp(tokens);
                } else if ("create".equalsIgnoreCase(cmd)) {
                    handleCreateGroup(tokens);
                } else if ("sendFile".equalsIgnoreCase(cmd)) {
//                    inputStream.close();
                    handleFile();
                }

                else {
                    String msg = "Unknown command: " + cmd + "\n";
                    outputStream.write(msg.getBytes());
                }
            }
        }
    }

    private void handleFile (){
        System.out.println("File handler called");
        try {
            System.out.println("File handler called");
//            DataInputStream input = new DataInputStream(clientSocket.getInputStream());
            DataInputStream inputStream = new DataInputStream(clientSocket.getInputStream());
            int fileNameLength = inputStream.readInt();
            System.out.println(fileNameLength);
            if (fileNameLength > 0) {
                byte[] fileNameBytes = new byte[fileNameLength];
                inputStream.readFully(fileNameBytes, 0, fileNameBytes.length);
                String fileName = new String(fileNameBytes);
                System.out.println(fileName);
                int fileContentLength = inputStream.readInt();
                System.out.println(fileContentLength);
                if (fileContentLength > 0) {
                    byte[] fileContentBytes = new byte[fileContentLength];
                    inputStream.readFully(fileContentBytes, 0, fileContentBytes.length);
                    System.out.println(fileContentBytes);

//                    File fileToDownload = new File(fileName);
                    FileOutputStream fileOutputStream = new FileOutputStream("D:\\bbb.txt");
                    fileOutputStream.write(fileContentBytes);
                    fileOutputStream.close();
                }
            }

这是客户端代码:

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
//        final File[] fileToSend = new File[1];
//        fileToSend[0] = "C:\\Users\\alvyi\\Downloads";
        File file = new File("D:\\aaa.txt");

        try {
            Socket socket = new Socket("localhost", 6000);
            DataInputStream inputStream = new DataInputStream(socket.getInputStream());

            DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
        while(true){
            System.out.println("In the Loop");

            dataOutputStream.write("login alvy alvy\n".getBytes(StandardCharsets.UTF_8));
            dataOutputStream.write("sendFile\n".getBytes(StandardCharsets.UTF_8));

            FileInputStream fileInputStream = new FileInputStream(file.getAbsolutePath());
            String fileName = file.getName();
            // Convert the name of the file into an array of bytes to be sent to the server.
            byte[] fileNameBytes = fileName.getBytes();
            // Create a byte array the size of the file so don't send too little or too much data to the server.
            byte[] fileBytes = new byte[(int)file.length()];
            // Put the contents of the file into the array of bytes to be sent so these bytes can be sent to the server.
            fileInputStream.read(fileBytes);
            // Send the length of the name of the file so server knows when to stop reading.
            dataOutputStream.writeInt(50);
            dataOutputStream.writeInt(fileNameBytes.length);
            // Send the file name.
            dataOutputStream.write(fileNameBytes);
            // Send the length of the byte array so the server knows when to stop reading.
            dataOutputStream.writeInt(fileBytes.length);
            // Send the actual file.
            dataOutputStream.write(fileBytes);



            String echoString = scanner.nextLine();
        }
    //        System.out.println(inputStream.readLine());

     //       outputStream.write("sendFile".getBytes());



        } catch (IOException e) {
            e.printStackTrace();
        }



    }
}

【问题讨论】:

    标签: java multithreading file chat serversocket


    【解决方案1】:

    在这种情况下,如何让服务器区分以下程序中的文件和文本?或者我可以像“file jony c://abc.txt”一样将 abc.txt 文件发送给 jony?

    可用性的角度来看,将send file 命令作为聊天 API 中的单独命令是有意义的。因此,添加一个不同的命令来使用像file 这样的描述性名称的想法是有意义的。

    如果要谈API的实现,那么这就是标准问题的标准解决方案。

    这里是code,它解释了如何通过套接字发送文件。

    【讨论】:

    • 是的,我这样做了,但看起来它什么也没做。但是,如果我在开始时调用该方法(当前已评论),它会起作用!!!我现在头疼:/
    • 那为什么不一开始就调用呢?
    • 那会破坏整个目的。我只想在客户端发送命令 sendFile 时发送文件。如果我一开始就使用它,那么我每次都需要发送一个文件,然后才能开始做其他事情。我已经更新了代码。如果可能的话,请看一下:(
    • 谢谢,终于明白了 BufferReader 导致了所有问题。使用 inputStream.readLine() 解决了这个问题。 (家庭它不会在未来引起问题哈哈)
    • 如果我的回答对您有所帮助,请随时将答案标记为已接受并点赞
    最近更新 更多