当前位置: 首页 > 知识库问答 >
问题:

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

翟淮晨
2023-03-14

我是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个答案

韦思淼
2023-03-14

问题出在< code>s_r_m()函数中。在< code>while循环中,第一条语句是< code > String str = dis . read utf();因此,这里的< code >客户端和< code >服务器将首先等待另一端的回复,这将导致< code >死锁。所以他们中的任何一个都不能发送任何数据,直到从另一边接收。

因此,您需要相应地更改代码。我已经实现了一个代码来解决这个问题,它从键盘(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();
    }
}

在这里,您可以更改从 STDIN 到应用程序中的文本字段的输入代码。所以每当用户按下发送按钮时,它就会将消息发送到另一端。

 类似资料:
  • 我有客户端服务器聊天 客户端发送文件,服务器接收它们。但是,问题是,我不认为文件被正确接收,因为当我检查文件的大小时,我看到由于某些原因差异是一半! 我正在使用GUI在客户端浏览文件,然后我向服务器发送命令以知道客户端正在发送文件。但是它不工作 这里是客户端和服务器 计算机网络服务器 有人能帮我解决这个问题吗?因为我不知道如何正确发送和接收文件 谢谢你

  • 服务器和客户端使用我自己的协议进行通信,看起来像XMPP。我应该实现聊天应用。因此,当一个用户编写String时,它应该立即通过服务器发送给其他客户端。我在服务器上有sendToAll方法。但用户只有在按下回车键时才能看到其他用户的消息。用户如何在不按回车键的情况下接收消息? 这是我的客户: 以及带有ServerThread的服务器。 服务器线程。

  • 问题内容: 服务器和客户端使用我自己的协议(类似于XMPP)进行通信。我应该实现聊天应用程序。因此,当一个用户写String时,应该立即将其通过服务器发送给其他客户端。我在服务器上有sendToAll方法。但是用户只有在按Enter时才能看到其他用户的消息。 用户如何在不按Enter键的情况下接收消息? 这是我的客户: 和带有ServerThread的服务器。 ServerThread。 问题答案

  • 问题内容: 我正在尝试在服务器和客户端之间进行文件传输,但是工作非常糟糕。基本上需要发生的是: 1)客户端将txt文件发送到服务器(我称为“ quotidiani.txt”) 2)服务器将其保存在另一个txt文件中(“ receive.txt”) 3)服务器运行脚本上对其进行修改并以其他名称保存(“ output.txt”)的脚本 。4)服务器将文件发送回客户端,客户端以相同的名称(final.t

  • 我已经实现了一个通过套接字进行通信的全局聊天。客户端写入一条消息,发送到服务器,然后服务器将消息发回给所有客户端。每个客户端都由一个名为ClientThread的类表示,因此每个客户端都是一个线程。每次新客户端连接时,我都会创建一个新的ClientThread实例,并将所有这些实例存储在列表中。现在我想实现一个私人聊天,这样每个客户端就可以私下与另一个客户端交谈(或者2,3或更多的群聊)。 我还想