java - 聊天选项发送文件

标签 java c tcp

我想创建一个带有发送文件选项的简单 TCP 聊天。
向其他客户端发送消息有效,但发送文件无效。我的聊天只发送几个字节的文件。

聊天的工作方式如下:服务器启动并等待客户端,客户端连接到服务器,它们可以通过服务器向其他客户端发送消息。我想允许与文件相同。

服务器是用 C 写的,客户端是用 Java 写的(我有这样的指导方针)。

服务器:

    for (i = 0; i < max_clients; i++) {
        sd = client_socket[i]; 

        memset(buffer, 0, 10000);
        if (FD_ISSET( sd , &readfds)) {
            if ((valread = read( sd , buffer, 1024)) == 0) {
                getpeername(sd, (struct sockaddr*)&address, (socklen_t*)&addrlen); 
                printf("Host disconnected , ip %s , port %d \n" , 
                    inet_ntoa(address.sin_addr) , ntohs(address.sin_port)); 



                close( sd ); 
                client_socket[i] = 0; 
            } 
            else {
                // When message "start" arrived download the file and send it back to other clients
                if (strcmp(buffer, "start") == 0) {
                    uint8_t buff[10000];
                    // Read chunks of file
                    while (read( sd , buff, sizeof(buff)) > 0) {

                        // Sending chunks of file to other clients
                        for(j=0; j<max_clients; j++) {
                            int outSock = client_socket[j];
                            if(outSock != master_socket && outSock != sd) {
                                send(outSock , buff , sizeof(buff) , 0 ); 
                            }
                    }

                    }
                } else {

                    buffer[valread] = '\0'; 
                    for(j=0; j<max_clients; j++) {
                        int outSock = client_socket[j];
                        if(outSock != master_socket && outSock != sd) {
                            send(outSock , buffer , strlen(buffer) , 0 ); 
                        }
                    }

                }

            } 
        } 
    }

客户:

@FXML
void sendFile(ActionEvent event) {
    FileChooser fileChooser = new FileChooser();
    File file = fileChooser.showOpenDialog(null);

    // Send "start" message to let server know that I'm going to send a file
    out.println("start");
    out.flush();

    try {

        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(fis);

        //Get socket's output stream
        OutputStream os = clientSocket.getOutputStream();

        //Read File Contents into contents array
        byte[] contents;
        long fileLength = file.length();
        long current = 0;

        while(current!=fileLength){
            int size = 10000;
            if(fileLength - current >= size)
                current += size;
            else{
                size = (int)(fileLength - current);
                current = fileLength;
            }
            contents = new byte[size];
            bis.read(contents, 0, size);
            os.write(contents);
            System.out.print("Sending file ... "+(current*100)/fileLength+"% complete!");
        }

        os.flush();
        System.out.println("File sent successfully!");

    } catch(Exception e) {

    }
}

public ChatWindowController() {

    try {
        clientSocket = new Socket("127.0.0.1", 54000);
        outToServer = new DataOutputStream(clientSocket.getOutputStream());
        inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        out = new PrintWriter(clientSocket.getOutputStream(), true);

        thread = new Thread() {
            @Override
            public void run() {
                try {

                    while(isRunning) {
                        if (ta_display != null) {
                            String message = inFromServer.readLine();
                            if (!isDownloadingFile) {
                                System.out.println(message);
                                ta_display.appendText(message + '\n');

                                if (message.equals("start")) {
                                    isDownloadingFile = true;
                                }
                            } else {

                                byte[] contents = new byte[10000];

                                //Initialize the FileOutputStream to the output file's full path.
                                FileOutputStream fos = new FileOutputStream("/example/test.png");
                                BufferedOutputStream bos = new BufferedOutputStream(fos);
                                InputStream is = clientSocket.getInputStream();

                                //No of bytes read in one read() call
                                int bytesRead = 0;

                                while((bytesRead=is.read(contents))!=-1)
                                    bos.write(contents, 0, bytesRead);

                                bos.flush();

                                System.out.println("File saved successfully!");

                            }
                        }

                    }

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

        thread.start();
    } catch(Exception e) {
        e.printStackTrace();
    }
}

当我点击按钮 sendFile 方法被调用时,然后我选择文件,我想发送这个文件,并与其他客户端下载它。

最佳答案

我写了一个类似的聊天例子https://github.com/foreverpersist/socket/blob/master/chatroom.c .

文件传输是通过P2P实现的

  1. 服务器告诉<IP:PORT>发送方和接收方的 s。
  2. 发送方和接收方直接相互连接。
  3. 发送方将文件发送给接收方。
  4. 发送方和接收方关闭连接。

正如您的项目中发生的情况,当传输路径为 Sender -> Server -> Receiver 的文件时,大文件的内容如果不小心处理可能会不完整。所以,我只传输路径为 Sender -> Receiver 的文件.

关于java - 聊天选项发送文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54079401/

相关文章:

java - VisualVM - "Used heap"中包含什么?

java.nio.SocketChannel 始终返回相同的数据

java - 在 Jackson 中反序列化 bson long 原始 json

python - 使用正则表达式解析文件并进行修改

python - 如何保证使用python asyncio发送的tcp数据?

c - 如何在接受多个客户端连接时设置 TCP 服务器超时

Python套接字发送在多次调用recv后不起作用

java - Sahi脚本的等效Java代码: _openWindow ("http://www.google.com" ,"defaultSahiPopup", [360,640]);

c - 在C中的字符串前后添加一些字母

c - 跟踪系统调用