java - 聊天程序在文件传输期间挂起?

标签 java

我有一个java聊天服务器和客户端,工作正常。我单独制作了一个服务器到客户端的文件传输程序,它也工作正常。但是,当我尝试将文件传输集成到聊天中时,文件正在传输,但在此期间,聊天程序只是卡住,以至于我什至无法在聊天框中输入任何内容,当传输结束时,事情变得正常。如何让它正常,就像聊天和文件传输同时进行,互不影响?

我的文件传输在服务器和客户端上都有 while 循环,我想知道这是因为 while 循环,我应该在文件传输的服务器和客户端代码上创建线程吗? 我的聊天系统就像,在服务器上,用户连接,线程在服务器上为该用户启动,用于从用户读取,然后它将这些消息从用户发送给每个人。 在客户端,线程用于从服务器读取消息,当用户键入消息时,它将其发送到服务器,然后服务器将消息返回给所有连接的人。

我认为问题出在客户端,因为我刚刚和我的 friend 在互联网上测试了这个,我是服务器,对于聊天和文件传输,我的聊天框很好,我可以打字,但是他的聊天客户端卡住文件传输发生的时间。

我不知道代码的哪一部分导致了这个问题,所以一旦有人提出要求,我就会用代码更新它..

谢谢, 任何帮助将不胜感激。

[编辑--客户端上的文件传输]

public class FileClient{


JFrame jfr;
JTextField Jtf = new JTextField(4);
public static void main (String [] args ) {

 // new FileClient().go();

 }

public void go(String ip){
    try{
    JFrame jfr = new JFrame("File Transfer");
            JPanel panel = new JPanel();
    JLabel jl = new JLabel("Progress:");
    jfr.getContentPane().add(BorderLayout.CENTER,panel);
    panel.add(jl);
    panel.add(Jtf);
    Jtf.setEditable(false);
    jfr.setSize(200,70);
    jfr.setVisible(true);
    jfr.setDefaultCloseOperation(jfr.EXIT_ON_CLOSE);
}catch(Exception e){e.printStackTrace();}
long start = System.currentTimeMillis();
    int read;
    int totalRead = 0;
    try{
    Socket sock = new Socket(ip,4243);
    System.out.println("Connecting...");
    InputStream is = sock.getInputStream();
    BufferedInputStream bis = new BufferedInputStream(new ProgressMonitorInputStream(jfr,"reading",is));

    byte [] mybytearray  = new byte [512];
    int buff =1024;
    byte[] nameByte = new byte [50];
    byte[] nameByteSize = new byte [2];
    byte[] Size = new byte [10];
    byte[] SizeSize =new byte [1];

    int num = is.read(nameByte,0,50);
    int nameSize = is.read(nameByteSize,0,2);
    int sz = is.read(Size,0,10);
    int yy = is.read(SizeSize,0,1);
    float w;

    String Size1 = RemoveNameStuffing(new String(Size),new String(SizeSize));
    int tt = Integer.parseInt(Size1);
    System.out.println("tt"+tt);
     name"+new String(nameByte));
    String name = RemoveNameStuffing(new String(nameByte),new String(nameByteSize));
    File f1=new File(name);

    FileOutputStream fos = new FileOutputStream(f1);
    BufferedOutputStream bos = new BufferedOutputStream(fos);

    while ((read = bis.read(mybytearray,0,mybytearray.length)) != -1) {
            bos.write(mybytearray, 0 , read);
            totalRead += read; 
            w=((float)totalRead/tt)*100;
            System.out.println("progress:"+w+"%");
            Jtf.setText(w+"%");
    }


    bos.flush();
    long end = System.currentTimeMillis();
    System.out.println(end-start);
    bos.close();
    sock.close();
    }catch(IOException e){e.printStackTrace();}
}

public static String RemoveNameStuffing(String s, String n){

    s=s.substring(0,Integer.parseInt(n));
    System.out.println("s:"+s);

    return s;

}

}

[编辑--这就是我将文件传输代码调用到聊天客户端的方式]

public class AcceptFileButtonListener implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
      FileCl.go(JTip.getText());
    }

}

[编辑--文件传输服务器代码--缓冲区大小 512]

//Waiting for connection
//Sending name in bytes
//While{
   send files as bytes
   }

[调用上述(FT 服务器)代码的聊天服务器]

public void actionPerformed(ActionEvent e) {

        FileSv.go();

    }

一旦我按下按钮,我的服务器也会卡住,即使 FT 服务器甚至没有建立连接(我认为这个 cud 有帮助)。

我有一个聊天服务器和客户端,两者都有可以互相读取的线程。我尝试将我的文件传输服务器和客户端集成到现有的聊天服务器和聊天客户端中。 最初,当用户连接到聊天服务器时,它会为其启动一个线程。现在要向该用户发送文件,我在服务器上创建了 1 个按钮(文件发送),在客户端上创建了 1 个按钮(接受文件),现在当我单击服务器上的“文件发送”时,我的文件传输服务器代码将被执行,并且文件传输服务器等待不同端口上的连接(我的聊天服务器现在卡住,它有一个文本字段,现在没有响应),现在如果与我正在完美聊天的用户单击“接受文件”文件传输客户端代码将被执行。 FT 服务器开始发送字节,FT 客户端接收它。服务器和客户端聊天窗口在传输发生时都变得无响应,并且我在传输期间从客户端聊天框发送的任何内容都会在传输后更新。 这是为了消除困惑。即使这没有帮助,我也会上传整个代码(太大了)

最佳答案

您正在经历在需要异步操作时使用同步操作的明显迹象。

我的猜测是,您的应用程序要么有一个线程,要么有一个远程通信线程。您可能没有使用 java 的 nio 类进行异步通信。

您可以查看 nio 类或在单独的线程中执行当前的文件发送和文件接收代码。

前者的实现可以在一个不错的 nio 教程中找到(这里是 one )。

后者的常见实现是使用命令模式发送消息/文件,以及带有生产者/消费者线程的命令队列。您可以将“Runnable”接口(interface)视为您的 Command 类。

public class MessageCommand implements Runnable {
    private String message;
    public MessageCommand(String message) { this.message = message; }
    public void run() { /* code to send the message goes here */ }
}

public class FileCommand implements Runnable {
    private File file; /* or byte[] or whatever */
    public MessageCommand(File file) { this.file = file; }
    public void run() { /* code to send the file goes here */ }
}

然后有某种Queue<Runnable> ,可能是 ConcurrentLinkedQueue,它接受这些类型的对象,并使用生产者/消费者。请注意,您还需要在代码的接收部分分离一个单独的线程。否则,您将能够异步发送,但在接收时会阻塞(这对于消息来说可能没问题,但对于文件来说很烦人)。

关于java - 聊天程序在文件传输期间挂起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8881836/

相关文章:

java - MIDlet-1。 NetBeans 中的错误

java - 初学者我的方法有什么问题

java - 使用 subscribeToStreamingNotifications 中的 Item.bind() 拒绝访问

Java- 将文本写入图像,然后写入输出文件

java - Azure 将 blob 容器复制到另一个具有不同层的 blob 容器 [java]

java - C 的 Crypt() 类似 Java 中的函数

java - 已编译的 lambda 函数中的额外参数从何而来?

java - 谷歌驱动器中谷歌文档的大小

java - .getClass().getName() 方法为何适用于 int 类型?

java - OpenMQ 和 JMX - 是否可以查询消息?