当前位置: 首页 > 面试题库 >

Java Swing GUI客户端和服务器聊天应用程序TextArea未更新

弓俊晖
2023-03-14
问题内容

我正在使用Java和针对Java的Swing类进行聊天应用程序。

ChatServer类将是从客户端接收消息并回显所有客户端的服务器,但我仅打算为2个客户端进行聊天。

ChatClient类都是客户端。它们在“文本区域”上显示从服务器发送的内容。并将“文本字段”中的文本发送到服务器。

ChatClient类

package chatclient;

import java.net.Socket;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStreamReader;

public class ChatClient extends javax.swing.JFrame {


public ChatClient() {
    initComponents();
}

/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    scrollPane = new javax.swing.JScrollPane();
    textArea = new javax.swing.JTextArea();
    btnConnect = new javax.swing.JButton();
    btnDisconnect = new javax.swing.JButton();
    lblStatus = new javax.swing.JLabel();
    lblShowStatus = new javax.swing.JLabel();
    txtInput = new javax.swing.JTextField();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setTitle("Chat Client A");

    textArea.setEditable(false);
    textArea.setColumns(20);
    textArea.setRows(5);
    textArea.setText("Welcome to the Chat Server. Type '/close' or Click 'Disconnect' to close.");
    textArea.setWrapStyleWord(true);
    textArea.setCaretPosition(textArea.getDocument().getLength());
    scrollPane.setViewportView(textArea);

    btnConnect.setText("Connect");
    btnConnect.setActionCommand("btnConnect");
    btnConnect.addMouseListener(new java.awt.event.MouseAdapter() {
        public void mouseClicked(java.awt.event.MouseEvent evt) {
            btnConnectMouseClicked(evt);
        }
    });

    btnDisconnect.setText("Disconnect");
    btnDisconnect.setActionCommand("btnDisconnect");
    btnDisconnect.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            btnDisconnectActionPerformed(evt);
        }
    });

    lblStatus.setText("Status: ");

    lblShowStatus.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
    lblShowStatus.setForeground(new java.awt.Color(255, 51, 51));
    lblShowStatus.setText("Disconnected");

    txtInput.setToolTipText("");
    txtInput.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            txtInputActionPerformed(evt);
        }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(scrollPane)
                .addGroup(layout.createSequentialGroup()
                    .addComponent(btnConnect)
                    .addGap(18, 18, 18)
                    .addComponent(btnDisconnect)
                    .addGap(42, 42, 42)
                    .addComponent(lblStatus)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(lblShowStatus)
                    .addGap(0, 42, Short.MAX_VALUE))
                .addComponent(txtInput))
            .addContainerGap())
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(scrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 213, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 11, Short.MAX_VALUE)
            .addComponent(txtInput, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(btnConnect)
                .addComponent(btnDisconnect)
                .addComponent(lblStatus)
                .addComponent(lblShowStatus))
            .addContainerGap())
    );

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

private void btnConnectMouseClicked(java.awt.event.MouseEvent evt) {                                        
    // TODO add your handling code here:
    lblShowStatus.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
    lblShowStatus.setForeground(new java.awt.Color(0, 204, 51));
    lblShowStatus.setText("Connected");

    // ADD CODES FOR CONNECTING TO CHAT SERVER

}

private void btnDisconnectActionPerformed(java.awt.event.ActionEvent evt) {                                              
    // TODO add your handling code here:
    lblShowStatus.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
    lblShowStatus.setForeground(new java.awt.Color(255, 51, 51));
    lblShowStatus.setText("Disconnected");

    // ADD CODES FOR DISCONNECTING FROM CHAT SERVER

}

private void txtInputActionPerformed(java.awt.event.ActionEvent evt) {                                         
    // TODO add your handling code here:
}

/**
 * @param args the command line arguments
 */
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(ChatClient.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(ChatClient.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(ChatClient.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(ChatClient.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 ChatClient().setVisible(true);
        }
    });

    String input = "", serverInput = "";
    String host = "localhost";
    int port = 1337;
    Socket client;

    // updateTextArea("TEST UPDATE");

    try {
        client = new Socket(host, port);
        System.out.println("Connected to Server!");

        DataInputStream in = new DataInputStream(client.getInputStream());
        DataOutputStream out = new DataOutputStream(client.getOutputStream());

        System.out.println("Before setting text area");
        updateTextArea("trying to update");

        do {
            // HANDLE INPUT PART HERE
            serverInput = in.readUTF();


            if(serverInput != null) {
                System.out.println("Reached here");
                System.out.println(serverInput);
                updateTextArea(serverInput); 
            }

        } while(!input.equals("/close"));
        System.out.println("Program closed");
    }

    catch(Exception exc) {
        System.err.println(exc.getMessage());
    }


}

private static void updateTextArea(String temp) {
    textArea.setText(textArea.getText() + "\n" + temp + "\n");
    textArea.setCaretPosition(textArea.getDocument().getLength());
}

// Variables declaration - do not modify                     
private javax.swing.JButton btnConnect;
private javax.swing.JButton btnDisconnect;
private javax.swing.JLabel lblShowStatus;
private javax.swing.JLabel lblStatus;
private javax.swing.JScrollPane scrollPane;
private static javax.swing.JTextArea textArea;
private javax.swing.JTextField txtInput;
// End of variables declaration                   
}

ChatServer类

package chatserver;

import java.io.BufferedReader;
import java.io.InputStreamReader;
// for testing
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 *
 * @author wacats
 */
public class ChatServer {
public static void main(String args[]) {
    int port = 1337;

    try {
        ServerSocket server = new ServerSocket(port);
        String inMessage = "";

        while(true) {
            Socket clientA = server.accept();
            DataInputStream inA = new DataInputStream(clientA.getInputStream());
            DataOutputStream outA = new DataOutputStream(clientA.getOutputStream());
            // outA.writeUTF("Welcome to the Chat Server. Type '/close' or Click 'Disconnect' to close.");

            // for testing
            // BufferedReader user = new BufferedReader(new InputStreamReader(System.in));

            do {
                inMessage = inA.readUTF();

                outA.writeUTF("testing");

                if(inMessage != null) {
                   outA.writeUTF(inMessage); 
                }

            } while(!inMessage.equals("/close"));
            clientA.close();
        }



    }

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

我对这个程序的过程的想法是:

  1. 启动ChatServer
  2. 启动ChatClient
  3. 当两个客户端都连接到服务器时,它们可以开始聊天。
  4. 按下“ Enter”将把“文本字段”中的文本发送到服务器。
  5. 服务器会将文本广播到两个客户端。
  6. 客户端将更新文本区域,附加从服务器接收的文本。

问题答案:

基本问题是,textAreanull,当你尝试和呼叫updateTextArea,这是因为invokeLater呼叫尚未执行,并构建了您的UI,你基本上有一个竞争条件。

Socket在Swing中处理s 的通常方法是使用SwingWorker

有关更多详细信息,请查看Swing和Worker线程中的并发性和SwingWorker。

您可以通过多种方式解决问题。您可以使用SwingWorker来从套接字读取文本并生成更新通知(通过publish/
process)方法,这通常称为“观察者模式”。这很好,因为它可以使您的代码脱钩并生成更可重用的解决方案。

这个类所做的只是从中读取文本,SocketActionEvent从文本生成s,很简单。

public class SocketReader extends SwingWorker<Void, String> {

    private List<ActionListener> actionListeners;

    public SocketReader() {
        actionListeners = new ArrayList<>(25);
    }

    public void addActionListener(ActionListener listener) {
        actionListeners.add(listener);
    }

    public void removeActionListener(ActionListener listener) {
        actionListeners.remove(listener);
    }

    @Override
    protected Void doInBackground() throws Exception {
        System.out.println("Connected to Server!");

        try (DataInputStream in = new DataInputStream(SocketManager.INSTACNE.getInputStream())) {

            System.out.println("Before setting text area");

            String serverInput = null;
            do {
                // HANDLE INPUT PART HERE
                serverInput = in.readUTF();

                if (serverInput != null) {
                    System.out.println("Read " + serverInput);
                    publish(serverInput);
                }

            } while (!serverInput.equals("/close"));
            System.out.println("Program closed");
        }
        return null;
    }

    @Override
    protected void process(List<String> chunks) {
        for (String text : chunks) {
            ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, text);
            for (ActionListener listener : actionListeners) {
                listener.actionPerformed(evt);
            }
        }
    }

}

SocketWriter

这个简单的将文字写入Socket,简单。从技术上讲,您不需要为此使用a SwingWorker,但是我喜欢这样的事实:取消它相对容易

public class SocketWriter extends SwingWorker<Void, Void> {

    private List<String> messages;
    private ReentrantLock lock;
    private Condition waitCon;

    public SocketWriter() {
        messages = Collections.synchronizedList(new ArrayList<String>(25));
        lock = new ReentrantLock();
        waitCon = lock.newCondition();
    }

    public void write(String text) {
        System.out.println("Write " + text);
        messages.add(text);
        try {
            lock.lock();
            waitCon.signalAll();
        } finally {
            lock.unlock();
        }
    }

    @Override
    protected Void doInBackground() throws Exception {
        try (DataOutputStream out = new DataOutputStream(SocketManager.INSTACNE.getOutputStream())) {
            while (!isCancelled()) {
                while (messages.isEmpty() && !isCancelled()) {
                    try {
                        lock.lock();
                        waitCon.await();
                    } finally {
                        lock.unlock();
                    }
                }
                List<String> cache = new ArrayList<>(messages);
                messages.clear();
                for (String text : cache) {
                    System.out.println("Send " + text);
                    out.writeUTF(text);
                }
            }
        }
        return null;
    }

}

SocketManager

好的,这对我来说有点过大了,但是我想要一个的中央控制器Socket,您不必使用单例,您可以简单地使其成为一个简单的类,并将其引用传递给您ChatClient,然后传递给SocketReader/Writer,但是很晚了,我很懒

public enum SocketManager {
    INSTACNE;

    private String host = "localhost";
    private int port = 1337;
    private Socket socket;

    public Socket open() throws IOException {
        if (socket != null) {
            close();
        }
        socket = new Socket(host, port);
        return socket;
    }

    public void close() throws IOException {
        if (socket == null) {
            return;
        }
        socket.close();
    }

    public boolean isOpen() {
        return socket != null
            && socket.isConnected()
            && !socket.isClosed()
            && !socket.isInputShutdown()
            && !socket.isOutputShutdown();
    }

    public InputStream getInputStream() throws IOException {
        Objects.requireNonNull(socket, "Socket is not open");
        return socket.getInputStream();
    }

    public OutputStream getOutputStream() throws IOException {
        Objects.requireNonNull(socket, "Socket is not open");
        return socket.getOutputStream();
    }
}

ChatClient

很棒,一切都很好,但是您打算如何使用它呢?

基本上,您将在中创建一个的实例,SocketReaderSocketWriter在中将ChatClient附加ActionListener到阅读器,并在JTextArea触发时更新,然后将要发送的文本发送到SocketWriter,例如。

public class ChatClient extends javax.swing.JFrame {

    public ChatClient() {
        initComponents();
        socketReader = new SocketReader();
        socketReader.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String text = e.getActionCommand();
                textArea.append(text);
                textArea.append("\n");
                textArea.setCaretPosition(textArea.getDocument().getLength());
            }
        });
        socketReader.execute();

        socketWriter = new SocketWriter();
        socketWriter.execute();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        scrollPane = new javax.swing.JScrollPane();
        textArea = new javax.swing.JTextArea();
        btnConnect = new javax.swing.JButton();
        btnDisconnect = new javax.swing.JButton();
        lblStatus = new javax.swing.JLabel();
        lblShowStatus = new javax.swing.JLabel();
        txtInput = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Chat Client A");

        textArea.setEditable(false);
        textArea.setColumns(20);
        textArea.setRows(5);
        textArea.setText("Welcome to the Chat Server. Type '/close' or Click 'Disconnect' to close.");
        textArea.setWrapStyleWord(true);
        textArea.setCaretPosition(textArea.getDocument().getLength());
        scrollPane.setViewportView(textArea);

        btnConnect.setText("Connect");
        btnConnect.setActionCommand("btnConnect");
        btnConnect.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                btnConnectMouseClicked(evt);
            }
        });

        btnDisconnect.setText("Disconnect");
        btnDisconnect.setActionCommand("btnDisconnect");
        btnDisconnect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnDisconnectActionPerformed(evt);
            }
        });

        lblStatus.setText("Status: ");

        lblShowStatus.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        lblShowStatus.setForeground(new java.awt.Color(255, 51, 51));
        lblShowStatus.setText("Disconnected");

        txtInput.setToolTipText("");
        txtInput.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtInputActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(scrollPane)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(btnConnect)
                        .addGap(18, 18, 18)
                        .addComponent(btnDisconnect)
                        .addGap(42, 42, 42)
                        .addComponent(lblStatus)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(lblShowStatus)
                        .addGap(0, 42, Short.MAX_VALUE))
                    .addComponent(txtInput))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(scrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 213, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 11, Short.MAX_VALUE)
                .addComponent(txtInput, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnConnect)
                    .addComponent(btnDisconnect)
                    .addComponent(lblStatus)
                    .addComponent(lblShowStatus))
                .addContainerGap())
        );

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

    private void btnConnectMouseClicked(java.awt.event.MouseEvent evt) {
        // TODO add your handling code here:
        lblShowStatus.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        lblShowStatus.setForeground(new java.awt.Color(0, 204, 51));
        lblShowStatus.setText("Connected");

        // ADD CODES FOR CONNECTING TO CHAT SERVER
    }

    private void btnDisconnectActionPerformed(java.awt.event.ActionEvent evt) {
        // TODO add your handling code here:
        lblShowStatus.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        lblShowStatus.setForeground(new java.awt.Color(255, 51, 51));
        lblShowStatus.setText("Disconnected");

        // ADD CODES FOR DISCONNECTING FROM CHAT SERVER
    }

    private void txtInputActionPerformed(java.awt.event.ActionEvent evt) {
        if (SocketManager.INSTACNE.isOpen()) {
            socketWriter.write(txtInput.getText());
        } else {
            System.out.println("!! Not open");
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {

        try {
            /* 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(ChatClient.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (InstantiationException ex) {
                java.util.logging.Logger.getLogger(ChatClient.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                java.util.logging.Logger.getLogger(ChatClient.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (javax.swing.UnsupportedLookAndFeelException ex) {
                java.util.logging.Logger.getLogger(ChatClient.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            }
            //</editor-fold>

            SocketManager.INSTACNE.open();

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

        } catch (IOException ex) {
            ex.printStackTrace();
        }
        //</editor-fold>

    }

    private SocketWriter socketWriter;
    private SocketReader socketReader;

    // Variables declaration - do not modify                     
    private javax.swing.JButton btnConnect;
    private javax.swing.JButton btnDisconnect;
    private javax.swing.JLabel lblShowStatus;
    private javax.swing.JLabel lblStatus;
    private javax.swing.JScrollPane scrollPane;
    private javax.swing.JTextArea textArea;
    private javax.swing.JTextField txtInput;
    // End of variables declaration                   
}

您会注意到,我曾SocketManager#openmain抱歉,错过了您的“连接”代码。我建议改为将其移至该方法;)

ChatServer

我对此没有做太多改变,但以防万一…

public class ChatServer {

    public static void main(String args[]) {
        int port = 1337;

        try {
            ServerSocket server = new ServerSocket(port);
            String inMessage = "";

            while (true) {
                System.out.println("Waiting");
                Socket clientA = server.accept();
                System.out.println("Connected");
                DataInputStream inA = new DataInputStream(clientA.getInputStream());
                DataOutputStream outA = new DataOutputStream(clientA.getOutputStream());
                // outA.writeUTF("Welcome to the Chat Server. Type '/close' or Click 'Disconnect' to close.");

                // for testing
                // BufferedReader user = new BufferedReader(new InputStreamReader(System.in));
                do {
                    inMessage = inA.readUTF();

                    if (inMessage != null) {
                        outA.writeUTF(inMessage);
                    }

                } while (!inMessage.equals("/close"));
                clientA.close();
            }

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

通常,当客户端连接时,您将启动一个新Thread客户端并让它处理客户端Socket,但这不是我的重点。

因此,基于所有这些,您需要大量阅读,包括Java中的并发性和全部关于套接字



 类似资料:
  • 我需要在netty中有一个客户机/服务器通信,用于我的项目目的之一。所以我刚开始用一个handsOn来改进,我正在学习netty,我是一个初学者。 我尝试了一个简单的客户端服务器与Netty聊天。 客户端和服务器正在初始化,我可以看到服务器能够获得用于建立连接的客户端管道,但是当客户端发送消息时,它没有进入ServerAdapterHandler的messageReceived部分。下面是我的源代

  • 我想在java上创建一个客户机/服务器应用程序,服务器的IP地址为192.168.1.100,在端口4500上等待客户机请求。 客户端从键盘上读取字符串,向服务器发送连接请求。一旦建立了连接,它就会将字符串发送到服务器。 这是我尝试的代码: 对于服务者: 对于客户端: 但这段代码有一个问题:

  • 本文向大家介绍Java多线程实现聊天客户端和服务器,包括了Java多线程实现聊天客户端和服务器的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了java聊天室代码,供大家参考,具体内容如下 主要涉及知识 ·Java中GUI程序的编写,包括事件监听机制。 ·Java的网络通信编程,ServerSocket,Socket类的使用。 ·Java中多线程的编程,Thread类,Runnable

  • 我正在使用聊天应用程序,我需要每一秒钟刷新一次列表。我使用处理程序重复调用该方法,但是它没有更新< code>ListView。我正在调用该方法中更改的通知数据集。 Messages.java 聊天适配器.java 更新的Message.java ChatDetail.xml ChatLeft.xml chattright . XML

  • 问题内容: 我使用nio频道构建了一个简单的聊天应用程序。我对网络和线程非常陌生。该应用程序用于与服务器通信(服务器/客户端聊天应用程序)。 我的问题是服务器不支持多个客户端。我该如何解决这个问题?我的代码中的错误是什么? 问题答案: 初学者Hello NIO Server的 理想之地