具有文件传输JAVA套接字的客户端/服务器聊天应用程序

时间:2017-04-15 07:54:49

标签: java sockets tcp

我是java的新手,我做了一个聊天应用程序,客户端和服务器可以通过它发送和接收消息,现在我试图从客户端发送文件到服务器,但是服务器,客户端和服务器接收到文件之后无法发送消息,以下是代码:

客户端:

import java.io.*;
import java.net.*;
import javax.swing.JFileChooser;

public class ClientFrame extends javax.swing.JFrame {

    static Socket s;
    static DataOutputStream dos1;
    static DataInputStream dis;
    static javax.swing.JTextArea jT;
    static JFileChooser fc = new JFileChooser();
    File file;

    public ClientFrame() {
        initComponents();
        jT = jTextArea1;
    }


    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
//send message
        try {
            String str1 = jTextField1.getText();
            String o = jT.getText() + "\n" + " Client ->" + str1;
            jT.setText(o);
            dos1.writeUTF(str1);
        } catch (Exception ex) {
        }
    }                                        

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
//open file chooser
        fc.showOpenDialog(this);
        file = fc.getSelectedFile();
        jTextField3.setText(file.getAbsolutePath());
    }                                        

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {                                         
//send file         
        try {
            String st = jT.getText() + "\n" + " Client -> " + "Sending a file";
            jT.setText(st);
            String str1 = "Client Sending a file,Press 'REC File' ";
            String st1 = "\n" + " Client ->" + str1;
            dos1.writeUTF(st1);
        } catch (Exception e) {
        }
        long length = file.length();
        byte[] bytes = new byte[65536];//65536 is max, i think
        InputStream in;
        try {
            in = new FileInputStream(file);
            OutputStream out = s.getOutputStream();
            int count;
            while ((count = in.read(bytes)) > 0) {
                out.write(bytes, 0, count);
            }
            out.close();
            in.close();
            s_r_m();
        } catch (Exception ex) {
        }
    }                                        

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ClientFrame().setVisible(true);
            }
        });
        try {
            s = new Socket("localhost", 3000);
        } catch (Exception e) {
        }
        s_r_m();
    }

    public static void s_r_m() {
        System.out.println("call srm");
        try {
            dis = new DataInputStream(s.getInputStream());
            dos1 = new DataOutputStream(s.getOutputStream());
            while (true) {
                String str = (String) dis.readUTF();
                String out = jT.getText() + "\n" + " Server ->" + str;
                jT.setText(out);
            }
        } catch (Exception ex) {
        }
    }
}

服务器端:

import java.io.*;
import java.net.*;
import javax.swing.JFileChooser;

public class ServerFrame extends javax.swing.JFrame {

    static ServerSocket ss;
    static Socket s;
    static DataInputStream dis;
    static DataOutputStream dos1;
    static javax.swing.JTextArea jT;
    static JFileChooser fc = new JFileChooser();
    File file;

    public ServerFrame() {
        initComponents();
        jT = jTextArea1;
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
//send message
        try {
            String str1 = jTextField1.getText();
            String out = jT.getText() + "\n" + " Server ->" + str1;
            jT.setText(out);
            dos1.writeUTF(str1);
        } catch (Exception ex) {
        }
    }                                        

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        //open file chooser
        fc.showOpenDialog(this);
        file = fc.getSelectedFile();
        jTextField3.setText(file.getAbsolutePath());
    }                                        


    private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {                                         
//rec file 
        InputStream in = null;
        OutputStream out = null;
        try {
            in = s.getInputStream();
            out = new FileOutputStream("F:\\yoMama.exe");
            int count;
            byte[] buffer = new byte[65536];
            while ((count = in.read(buffer)) > 0) {
                out.write(buffer, 0, count);
            }
            String o = jT.getText() + "\n" + " Client ->" + " File received";
            jT.setText(o);
            out.close();
            in.close();
            s_r_m();
        } catch (Exception ex) {
        }
    }                                        
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ServerFrame().setVisible(true);
            }
        });
        try {
            ss = new ServerSocket(3000);
            s = ss.accept();//will accept connection from client,waiting state untill client connects
            s_r_m();

        } catch (Exception e) {
        }
    }

    public static void s_r_m() {
        System.out.println("call srm");
        try {
            dis = new DataInputStream(s.getInputStream());
            dos1 = new DataOutputStream(s.getOutputStream());

            while (true) {
                String str = dis.readUTF();
                String out = jT.getText() + "\n" + " Client ->" + str;
                jT.setText(out);
            }
        } catch (Exception ex) {
        }
    }
}

1 个答案:

答案 0 :(得分:1)

问题出在s_r_m()函数中。在while循环中,第一个语句是String str = dis.readUTF();所以此处ClientServer都将等待来自另一方的回复,这将最终以Deadlock结尾。所以他们中的任何一方都无法发送任何数据,直到从另一方收到。

因此您需要相应地更改代码。我已经实现了一个代码来解决这个问题,它从Key-Board(STDIN)输入。

DataInputStream dis=new DataInputStream(sckt.getInputStream());
DataInputStream dis1=new DataInputStream(System.in);
DataOutputStream dos=new DataOutputStream(sckt.getOutputStream());

String str="";
while(true)
{
    while(dis.available()>0) //If input is available from the other side.
    {
         String out = jT.getText() + "\n" + " Client ->" + dis.readUTF();
         jT.setText(out);
    }

    while(dis1.available()>0) //If input is available from STDIN to send it to the other side.
    {
        str=sc.nextLine();
        dos.writeUTF(str);
        dos.flush();
    }
}

您可以在此处更改从应用程序中的STDINText-Field的输入代码。因此,每当用户按下Send按钮时,它会将消息发送到另一方。