1

我的问题是,我仍然可以在客户端(客户端到客户端)之间发送消息,但是发送两三次后,消息不再显示给收件人。

所以基本上每当客户端希望向另一个客户端发送消息时,消息首先被发送到服务器。但是正如您从我的编码中注意到的那样,我正在以对象的形式发送服务器数据。例如:

send(new ChatMessage(type, sender, content, recipient));

当您发送消息时,类型为“消息”。当服务器接收到对象时,它会检查接收到的数据及其类型。例如:

ChatMessage cm = (ChatMessage) in[client[id].readObject();
if(cm.type.equals("message"){
  send(findUserThread(toWhom), new ChatMessage("message", sender, content, recipient);

}

如果类型是“消息”,那么它将向该特定客户端发送消息。

我在客户端使用 System.out.println() 来查看来自服务器的传入数据。因此,当我尝试发送一些消息时,它工作正常,但在发送一些消息后,我的聊天屏幕上没有显示任何内容。

根据我的逻辑,错误可能是:

1 JList 中的选定索引

2 Client[] 数组或 username[] 数组

3 对象输出流和对象输入流

ServerGUI 类(服务器端)

package test2;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.*;
import java.util.zip.GZIPOutputStream;
import javax.swing.SwingUtilities;

public class ServerGUI extends JFrame implements ActionListener {

public JList online;
private JTextField ipaddress, textMessage;
private JButton send, start, disconnect;
private JTextArea chatArea;
private JLabel port;
int client[] = new int[100];
private ObjectOutputStream out[] = new ObjectOutputStream[client.length + 1];
private ObjectInputStream in[] = new ObjectInputStream[client.length + 1];
String username[] = new String[client.length + 1];
static String b;
public String nm, usm;
private ServerSocket server;
private Socket connect;
boolean success = true;
int id = 0;
ArrayList<String> UserList = new ArrayList<String>();


public ServerGUI() {
    Container c = getContentPane();
    c.setLayout(new BorderLayout());
    c.setPreferredSize(new Dimension(650, 500));


    JPanel p = new JPanel();
    p.setLayout(new FlowLayout());
    p.setBackground(Color.LIGHT_GRAY);
    p.add(port = new JLabel("Port No"));
    p.add(ipaddress = new JTextField("1500"));
    p.add(start = new JButton("START"));
    p.add(disconnect = new JButton("DISCONNECT"));
    disconnect.setEnabled(false);
    start.setBorderPainted(false);
    start.setBackground(Color.blue);
    start.setForeground(Color.WHITE);
    disconnect.setBorderPainted(false);
    disconnect.setBackground(Color.blue);
    disconnect.setForeground(Color.WHITE);
    ipaddress.setCaretPosition(0);

    JPanel p1 = new JPanel();
    p1.setLayout(new FlowLayout());
    p1.setBackground(Color.LIGHT_GRAY);
    p1.add(chatArea = new JTextArea());

    chatArea.setPreferredSize(new Dimension(300, 350));
    chatArea.setLineWrap(true);
    chatArea.setEditable(false);

    JPanel p2 = new JPanel();
    p2.setLayout(new FlowLayout());
    p2.setBackground(Color.LIGHT_GRAY);
    p2.add(textMessage = new JTextField(20));

    p2.add(send = new JButton("SEND"));
    send.setBackground(Color.blue);
    send.setForeground(Color.WHITE);
    send.setBorderPainted(false);

    start.addActionListener(this);
    send.addActionListener(this);


    c.add(p, BorderLayout.NORTH);
    c.add(p1, BorderLayout.CENTER);
    c.add(p2, BorderLayout.SOUTH);


}
//current time
SimpleDateFormat log = new SimpleDateFormat("HH:mm");
String d = log.format(new Date());

//Start server
public void Start() {

    int portNo = 0;
    try {

        String no = ipaddress.getText();
        portNo = Integer.parseInt(no);
        chatArea.append("Connection to port " + portNo + "...\n");
        server = new ServerSocket(portNo);
        success = true;

    } catch (Exception ex) {
        chatArea.append("Error cannot bind to port \n");
        success = false;
    }

    if (success == true) {
        addClient ob1 = new addClient("RunServer");
        start.setEnabled(false);
        disconnect.setEnabled(true);
    }
}

public class addClient implements Runnable {

    Thread t;

    addClient(String tot) {
        t = new Thread(this, tot);
        t.start();
    }

    public void run() {
        while (true) {
            try {
                try {
                    WaitClient();
                } catch (Exception ex) {
                    break;
                }

                for (int i = 0; i < client.length; i++) {
                    if (client[i] == 0) {
                        client[i] = i + 1;
                        id = i;
                        break;
                    }
                }

                //set stream to send and receive data
                out[client[id]] = new ObjectOutputStream(connect.getOutputStream());
                out[client[id]].flush();
                in[client[id]] = new ObjectInputStream(connect.getInputStream());
                chatArea.append(d + " Client:[" + client[id] + "] : Connected successful \n");
                chatArea.setCaretPosition(chatArea.getText().length());
                //inform user that connection is successfull                    
                ChatMessage cm = (ChatMessage) in[client[id]].readObject(); // read client username
                if(cm.type.equals("login")){
                    chatArea.append("User " +cm.sender + " connected successfully" + "\n" );
                    username[client[id]] = cm.sender;
                    System.out.println(username[0]+ username[1]+ username[2]);
                    send(client[id], new ChatMessage("login", username[client[id]], "user", "SERVER"));
                    sendUserList(cm.sender);
                    Announce("newuser", "SERVER", cm.sender);




                }




                Chat c = new Chat(client[id], "StartChat" + client[id]); // make new thread for every new client 

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


    }

}

public class Chat implements Runnable {

    int id1;
    Chat ob1;
    Thread t;

    Chat(int id1, String info1) {
        this.id1 = id1; // create a thread for client
        t = new Thread(this, info1);
        t.start();
    }

    public void run() {
     boolean running = true;
       while(running){
            try {
                ChatMessage cm = (ChatMessage) in[client[id]].readObject(); // read client username
                if(cm.type.equals("message")){

                         send(findUserThread(cm.recipient), new ChatMessage(cm.type, cm.sender, cm.content, cm.recipient));


                }

            } catch (Exception e) {

            }
       }

    }
}




//wait for connection, then display connection information
private void WaitClient() throws IOException {

    chatArea.append(d + " : Waiting for connection... \n");
    connect = server.accept();

    chatArea.append(d + " : Now connected to " + connect.getInetAddress().getHostName() + "\n");
}

//send message to specific user
public void sendUser(int number, String info) {

    try {
        out[number].writeObject(info);
        out[number].flush();
    } catch (Exception e) {
    }

}

public void sendServer(String por) {
    for (int i = 0; i < client.length; i++) // for loop trying to send message from server to all clients 
    {
        if (client[i] != 0) // this line stop server to send messages to offline clients
        {
            try {
                out[i + 1].writeObject(por);
                out[i + 1].flush();
            } catch (Exception e) {
            }
        }
    }
}

public void Announce(String type, String sender, String content){

    ChatMessage cm = new ChatMessage(type, sender, content, "All");
    for(int i = 0; i < id; i++){
        send(client[i], cm);
    }
}



public void send(int number, ChatMessage cm) {

    try {
        out[number].writeObject(cm);
        out[number].flush();
    } catch (Exception e) {
    }

}





void sendAll(int num, String por) {
    for (int i = 0; i < client.length; i++) // for loop trying to send message from server to all clients 
    {
        if (client[i] != 0) // this line stop server to send messages to offline clients (if "clientNiz[X] = 0" don't try to send him message, because that slot is empty)
        {
            if (num != i + 1) // don't repeat messages (when for ex. client_1 send message to all clients, this line stop server to send same message back to client_1)
            {
                try {
                    out[i + 1].writeObject(por);
                    out[i + 1].flush();
                } catch (Exception e) {
                }
            }
        }
    }
}

public void sendUserList(String toWhom){
    for(int i = 0; i <= id; i++){
        send(findUserThread(toWhom), new ChatMessage("newuser", "SERVER", username[client[i]], toWhom));
    }
}

public int findUserThread(String usr){
    for(int i = 0; i <= id; i++){
        if(username[client[i]].equals(usr)){
            return client[i];
        }

    }
    return -1;
}

  private int findClient(int num){  
    for (int i = 0; i <= id; i++){
        if (client[i] == (num+1)){
                return i;
            }
}
return -1;
}





public void actionPerformed(ActionEvent e) {
    if (e.getSource() == send) {
        //current time

        String s1 = textMessage.getText();
        send(client[id], new ChatMessage("message", "admin", s1, "client"));
        chatArea.append("Administrator: " + s1 + "\n");


    } else if (e.getSource() == start) {
        Start();
    }
    if (e.getSource() == disconnect) {

        try {
            server.close();
        } catch (Exception ex) {
        }

        for (int i = 0; i < client.length; i++) {
            try {
                in[i].close();
                out[i].close();
            } catch (Exception ex) {
            }
        }
        chatArea.append("Server is disconnected\n");
        start.setEnabled(true);
        disconnect.setEnabled(false);
    }
}
}

MainGUI 类(客户端)

package test2;

import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;


public class MainGUI extends javax.swing.JFrame {

public MainGUI() {
    initComponents();





}

@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

    jButton1 = new javax.swing.JButton();
    jButton3 = new javax.swing.JButton();
    start = new javax.swing.JButton();
    jLabel2 = new javax.swing.JLabel();
    textMessage = new javax.swing.JTextField();
    jScrollPane2 = new javax.swing.JScrollPane();
    chatArea = new javax.swing.JTextArea();
    usernm = new javax.swing.JTextField();
    jLabel1 = new javax.swing.JLabel();
    send = new javax.swing.JButton();
    upload = new javax.swing.JButton();
    filename = new javax.swing.JTextField();
    jScrollPane1 = new javax.swing.JScrollPane();
    online = new javax.swing.JList();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setTitle("ICARE ");
    setFocusable(false);
    setPreferredSize(new java.awt.Dimension(840, 650));
    setResizable(false);
    getContentPane().setLayout(null);

    jButton1.setText("Video Call");
    getContentPane().add(jButton1);
    jButton1.setBounds(270, 10, 100, 30);

    jButton3.setText("Send");
    jButton3.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton3ActionPerformed(evt);
        }
    });
    getContentPane().add(jButton3);
    jButton3.setBounds(690, 100, 100, 30);

    start.setBackground(new java.awt.Color(51, 51, 255));
    start.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
    start.setForeground(new java.awt.Color(255, 255, 255));
    start.setText("Start");
    start.setBorder(null);
    start.setBorderPainted(false);
    start.setRequestFocusEnabled(false);
    start.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            startActionPerformed(evt);
        }
    });
    getContentPane().add(start);
    start.setBounds(630, 50, 90, 40);
    getContentPane().add(jLabel2);
    jLabel2.setBounds(0, 0, 820, 0);
    getContentPane().add(textMessage);
    textMessage.setBounds(270, 450, 420, 70);

    chatArea.setColumns(20);
    chatArea.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N
    chatArea.setRows(5);
    jScrollPane2.setViewportView(chatArea);

    getContentPane().add(jScrollPane2);
    jScrollPane2.setBounds(270, 140, 520, 300);
    getContentPane().add(usernm);
    usernm.setBounds(450, 60, 170, 30);

    jLabel1.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
    jLabel1.setText("Enter your nickname:");
    getContentPane().add(jLabel1);
    jLabel1.setBounds(270, 60, 150, 30);

    send.setBackground(new java.awt.Color(51, 51, 255));
    send.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
    send.setForeground(new java.awt.Color(255, 255, 255));
    send.setText("Send");
    send.setBorder(null);
    send.setBorderPainted(false);
    send.setRequestFocusEnabled(false);
    send.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            sendActionPerformed(evt);
        }
    });
    getContentPane().add(send);
    send.setBounds(700, 470, 90, 40);

    upload.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N
    upload.setText("+");
    upload.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            uploadActionPerformed(evt);
        }
    });
    getContentPane().add(upload);
    upload.setBounds(633, 100, 50, 30);
    getContentPane().add(filename);
    filename.setBounds(270, 100, 350, 30);

    jScrollPane1.setViewportView(online);

    getContentPane().add(jScrollPane1);
    jScrollPane1.setBounds(30, 20, 220, 500);

    pack();
}// </editor-fold>

private void startActionPerformed(java.awt.event.ActionEvent evt) {                                      
    Start();


}                                     

private void sendActionPerformed(java.awt.event.ActionEvent evt) {                                     
    // TODO add your handling code here:
    String z = textMessage.getText();
    String target = online.getSelectedValue().toString();
    chatArea.append("[ " + usernm.getText() + " ] : " + z + "\n");

    send(new ChatMessage("message", usernm.getText(), z, target));
    textMessage.setText("");         


}                                    

private void uploadActionPerformed(java.awt.event.ActionEvent evt) {                                       
    // TODO add your handling code here:
    //Create a file chooser
//In response to a button click:
JFileChooser fileChooser = new JFileChooser();
    fileChooser.showDialog(this, "Select File");
    file = fileChooser.getSelectedFile();

    if(file != null){
        if(!file.getName().isEmpty()){
            String str;

            if(filename.getText().length() > 30){
                String t = file.getPath();
                str = t.substring(0, 20) + " [...] " + t.substring(t.length() - 20, t.length());
            }
            else{
                str = file.getPath();
            }
            filename.setText(str);
        }
    }
}                                      

private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    // TODO add your handling code here:
      long size = file.length();
        if(size < 120 * 1024 * 1024){
            sendUser("download");


        }
        else{
            chatArea.append("File is size too large\n");
        }
}                                        

public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(MainGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(MainGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(MainGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(MainGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new MainGUI().setVisible(true);

        }
    });
}
// Variables declaration - do not modify
public javax.swing.JTextArea chatArea;
private javax.swing.JTextField filename;
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton3;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
public javax.swing.JList online;
private javax.swing.JButton send;
private javax.swing.JButton start;
private javax.swing.JTextField textMessage;
private javax.swing.JButton upload;
private javax.swing.JTextField usernm;
// End of variables declaration


private ObjectOutputStream out;
private ObjectInputStream in;
static String b; //variable for message
private Socket join;
boolean success = true;
private String serverIP = "127.0.0.1"; //set IP Address
ArrayList<String> userlist = new ArrayList<String>(); //ArrayList to store online users
//current time
SimpleDateFormat log = new SimpleDateFormat("HH:mm");
String d = log.format(new Date());
public File file;
public DefaultListModel model = new DefaultListModel();



//Start client program
public void Start() {

    try {

        start.setEnabled(false);
        chatArea.append(d + " : Attempting connection... \n");

        join = new Socket(serverIP, 10500);
        chatArea.append(d + " : Connected to - " + join.getInetAddress().getHostName() + "\n");

        success = true;

    } catch (Exception ex) {
        chatArea.append("Error cannot bind to port \n");            
        success = false;
    }

    if (success == true) {

        ClientThread ct = new ClientThread();


    }
}

class ClientThread implements Runnable {

    ClientThread ct;
    Thread t;

    ClientThread() {
        t = new Thread(this, "RunClient");
        t.start();

    }

    public void run() {
        try {
            try {
                out = new ObjectOutputStream(join.getOutputStream());
                out.flush();
                in = new ObjectInputStream(join.getInputStream());

                send(new ChatMessage("login", usernm.getText(), "password", "SERVER"));                
            } catch (Exception e) {   }



            CThread c1 = new CThread();


        } catch (Exception ex) {   }
    }
}

class CThread implements Runnable {

    CThread ob1;
    Thread t;

    CThread() {
        t = new Thread(this, "Message");
        t.start();
    }


    public void run() {
        boolean running = true;
        try {
            while(running){
                try {

                    ChatMessage cm = (ChatMessage) in.readObject();
                    System.out.println("Incoming :" + cm.toString());
                    if(cm.type.equals("login")){
                     chatArea.append(cm.sender + " is online" + "\n");
                    }else if(cm.type.equals("message")){                           
                        if(cm.recipient.equals(usernm.getText())){
                                 chatArea.append("[ "+cm.sender +" ] : " + cm.content + "\n");

                        }
                   }else if(cm.type.equals("newuser")){

                        online.setModel(model);
                        model.addElement(cm.content);
                    }

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





void sendUser(String por) {
    try {
        out.writeObject(por);
        out.flush();
    } catch (Exception e) {
    }
}

void send(ChatMessage cm){
    try {
        out.writeObject(cm);
        out.flush();
    } catch (Exception e) {
    }

}


}

聊天消息类

package test2;

import java.io.Serializable;

public class ChatMessage implements Serializable{

private static final long serialVersionUID = 1L;
public String type, sender, content, recipient;

public ChatMessage(String type, String sender, String content, String recipient){
    this.type = type; this.sender = sender; this.content = content; this.recipient = recipient;
}

@Override
public String toString(){
    return "{type='"+type+"', sender='"+sender+"', content='"+content+"', recipient='"+recipient+"'}";
}
}

ServerTest 运行 ServerGUI

公共类 ServerTest { public static void main(String args[]){

    ServerGUI m = new ServerGUI();

    m.setTitle("Server");

    m.setVisible(true);

    m.pack();

    //to make to the center of the screen

    m.setLocationRelativeTo(null);


}
}
4

2 回答 2

0

但是发送两三条消息后,我的程序停止发送消息

首先,您应该尝试调试您的应用程序。使用日志,或者System.out.println您可以轻松找出它“停止”的位置。消息是否正在发送到服务器?服务器是否将消息发送给客户端?只需几个 . 你就可以回答这些问题println

一旦你知道它在哪里(在你的代码中,哪种方法)失败了,如果你仍然需要帮助,你可以发布一个更具体的问题。

另外,当您遇到问题时,请详细说明问题的真正原因。应用程序会崩溃吗?它会停止向所有人发送消息吗?“我的程序停止发送消息”有点含糊。

编辑:好吧,既然我看到了代码,请不要这样做:

void send(ChatMessage cm){
    try {
        out.writeObject(cm);
        out.flush();
    } catch (Exception e) {
    }
}

如果抛出异常,您将不会注意到。
您应该添加:

e.printStackTrace();

每个 catch()块内,以便您可以在控制台中看到错误发生时。

没有人喜欢控制台中的红色消息,但隐藏它们无济于事。总是打印错误,或记录它们,或两者兼而有之:)

于 2013-03-04T11:53:36.717 回答
0
  • Java 中的类应该以大写字母开头。例如:ServerGUI但不像addClient您的代码中看到的那样。
  • 类代表对象。或对象的“类”。例如CarorServerGUI但不是addClient。什么是new addClient()? 那真的是一个物体吗?
  • 如果可能,变量名称应该具有重要的名称。例如Car limousine = new Car(4,Color.Black)而不是addClient ob1 = new addClient("RunServer")。是什么ob1意思?
  • 评论对读者来说是新鲜空气。请使用评论。例如://we are going to represent the server as a special user with admin privileges
  • ir Java 中的方法名称不应以大写开头。这是一个不好的例子:private void WaitClient() throws IOException
  • 缩进和空行。不知道是部分还是完全是你的错,但是代码缩进不好,块内有空行(不仅仅是一两个,也不是分隔符),并且缺少空格(if(cm.type.equals("login")){
  • StackOverflow 不是解决您问题的好地方。人们在这里提出具体问题。你的不是一个具体的问题,它更像是一个“我的程序不起作用”的问题。

总之:您的代码很难阅读和理解。看来您是 Java 新手,所以请从简单易行的示例开始,使用 Eclipse 或 Netbeans 等 Java IDE,慢慢来!你不会在一周内学习 Java,请耐心等待。

对不起,如果我太诚实了,但这就是我的想法(这可能是这里没有其他人帮助你的原因之一)。

于 2013-03-05T11:23:00.080 回答