我的问题是,我仍然可以在客户端(客户端到客户端)之间发送消息,但是发送两三次后,消息不再显示给收件人。
所以基本上每当客户端希望向另一个客户端发送消息时,消息首先被发送到服务器。但是正如您从我的编码中注意到的那样,我正在以对象的形式发送服务器数据。例如:
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);
}
}