简体   繁体   中英

java - chat program hangs during file transfer?

i have a java chat server & client, that works fine. I made a server to client file transfer program separately, it is also working fine. But when i try to integrate the file transfer into chat, the file is getting transferred, but during that time, the chat program just freezes, so much that i can't even type a thing into the chat box, and when transfer gets over, things get normal. how to make it normal, like chatting and file transfer is taking place side by side, none gets affected by the other?

My file transfer has while loops on both server and client, i wanted to know that is this because of while loops, should i create threads on both file transfer's server and client code. My Chat System is like, on server,user connects, threads starts on server for that user, for reading from user, it then sends these messages from user to everyone. On client, threads are for reading from server, when user types messages, it send it to server, which then return messages to everyone connected.

i think the problem is on Client side, as i just tested this on internet with my friend, i was the server, for both Chat & File Transfer, my chat box was fine, i was able to type, but his chat client freezd for the time file transfer took place.

i don't know which part of code is causing this, so i'll update this with code, as soon as someone asks for it..

Thanks, Any help wud be appreciated.

[EDIT--FILE TRANSFER ON CLIENT]

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;

}

}

[EDIT--THIS IS HOW I AM CALLING FILE TRANSFER CODE INTO CHAT CLIENT]

public class AcceptFileButtonListener implements ActionListener {

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

}

[EDIT--FILE TRANSFER SERVER CODE--BUFFER SIZE 512]

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

[CHAT SERVER WHERE ABOVE (FT SERVER) CODE IS CALLED]

public void actionPerformed(ActionEvent e) {

        FileSv.go();

    }

and my server also freezes as soon as i press the button, even when the FT server has not even got a connection(i think this cud help).

i have a chat server and client, both having threads to read from each other. i tried to integrate my File transfer server and client into existing chat server and chat client. initially when user connects to chat server, it starts a thread for it. now to send a file to that user, i created 1 button on server(file send) and 1 on client(accept file), now as i click onto "file send" on server, my File transfer server code gets executed, and File transfer Sever wait for a connection on different port(my chat server now freezes, it has a textField, which is unresponsive now), now if the user with whom i am chatting perfectly, clicks on "accept file" File transfer client code gets executed. FT server starts sending bytes, FT client rcvs it. both the server and client CHAT window becomes unresponsive for the time transfer takes place, and whatever i have sent from the client side chat box during transfer, gets updated after transfer. This is to clear the confusion. even if this doesn't help, i will upload whole code(which is too big)

You are experiencing the tell-tale sign of using synchronous operations while you want asynchronous operations.

My guess is that you have either a single thread for your application or a single thread for your remote communication. You are likely not using java's nio classes for asynchronous communication.

You could either look into the nio classes or execute your current file-sending and file-receiving code in a separate thread.

The implementation for the former can be found in a decent nio tutorial (here's one ).

A common implementation for the latter is to use the command pattern for sending messages/files, and a command queue with producer/consumer threads. You can treat the "Runnable" interface as your Command class.

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 */ }
}

Then have some kind of Queue<Runnable> , possibly ConcurrentLinkedQueue, that takes objects of these types, and use the producer/consumer. Note that you will also need to spin off a separate thread on the receiving part of the code as well. Otherwise, you will be able to send asynchronously, but will block while receiving (which might be ok for messages, but annoying for files).

Ok, to expand my comment - you say when clicked on a button on the clientchat window, FileTransferClient side is initiated, which works on while loop to read byte from server.

Are you running your file transfer code in the Swing Event thread? If so, you need to wrap it inside a Runnable object, ensure that its yielding up some processing time between iterations of the while loops, and invoke it using SwingUtilities.

If you're starting a separate thread on the button press in order to transfer the file, you still need to yield up processing time between loops of your sending loop or you're not yielding any processing time to the chat processing threads.

edit: amend your action listener call to do the following:

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

What this does is move the CPU and IO intensive processing of your file download into a new thread, external to the Swing event thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM